Bläddra i källkod

adding MHD_set_response_options function

Christian Grothoff 11 år sedan
förälder
incheckning
ea8bac4745

+ 6 - 0
ChangeLog

@@ -1,3 +1,9 @@
+Sun Jun  8 15:10:44 CEST 2014
+	Add 'MHD_set_response_options' as a way to set per-response
+	flags.  Add flag to force HTTP 1.0-only conservative
+	behavior, in particular suppressing adding "Connection"
+	headers. -CG
+
 Mon Jun  2 00:03:28 CEST 2014
 	Added back unescaping for URI path (#3413) but without
 	unescaping '+' (#3371) to remain compatible with

+ 56 - 0
doc/libmicrohttpd.texi

@@ -958,6 +958,33 @@ own private copy of the data for processing.
 @end deftp
 
 
+@deftp {Enumeration} MHD_ResponseFlags
+Response-specific flags.  Passed as an argument to
+@code{MHD_set_response_options()}.
+
+@table @code
+@item MHD_RF_NONE
+No special handling.
+
+@item MHD_RF_HTTP_VERSION_1_0_ONLY
+Only respond in conservative HTTP 1.0-mode.   In particular,
+do not (automatically) sent "Connection" headers and always
+close the connection after generating the response.
+
+@end table
+@end deftp
+
+
+@deftp {Enumeration} MHD_ResponseOptions
+Response-specific options.  Passed in the varargs portion of
+@code{MHD_set_response_options()}.
+
+@table @code
+@item MHD_RO_END
+No more options / last option.  This is used to terminate the VARARGs
+list.
+@end table
+@end deftp
 
 
 @c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -1559,6 +1586,7 @@ response and we finally destroy it only when the daemon shuts down.
 * microhttpd-response enqueue:: Enqueuing a response.
 * microhttpd-response create::  Creating a response object.
 * microhttpd-response headers:: Adding headers to a response.
+* microhttpd-response options:: Setting response options.
 * microhttpd-response inspect:: Inspecting a response object.
 @end menu
 
@@ -1852,6 +1880,34 @@ Delete a header (or footer) line from the response.  Return @code{MHD_NO} on err
 @end deftypefun
 
 
+@c ------------------------------------------------------------
+@node microhttpd-response options
+@section Setting response options
+
+
+@deftypefun int MHD_set_response_options (struct MHD_Response *response, enum MHD_ResponseFlags flags, ...)
+Set special flags and options for a response.
+
+Calling this functions sets the given flags and options for the response.
+
+@table @var
+@item response
+which response should be modified;
+
+@item flags
+flags to set for the response;
+
+@end table
+
+Additional arguments are a list of options (type-value pairs,
+terminated with @code{MHD_RO_END}). It is mandatory to use
+@code{MHD_RO_END} as last argument, even when there are no
+additional arguments.
+
+Return @code{MHD_NO} on error, @code{MHD_YES} on success.
+@end deftypefun
+
+
 @c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 @c ------------------------------------------------------------

+ 48 - 1
src/include/microhttpd.h

@@ -130,7 +130,7 @@ typedef intptr_t ssize_t;
  * Current version of the library.
  * 0x01093001 = 1.9.30-1.
  */
-#define MHD_VERSION 0x00093700
+#define MHD_VERSION 0x00093701
 
 /**
  * MHD-internal return code for "YES".
@@ -1745,6 +1745,53 @@ MHD_resume_connection (struct MHD_Connection *connection);
 
 /* **************** Response manipulation functions ***************** */
 
+
+/**
+ * Flags for special handling of responses.
+ */
+enum MHD_ResponseFlags
+{
+  /**
+   * Default: no special flags.
+   */
+  MHD_RF_NONE = 0,
+
+  /**
+   * Only respond in conservative HTTP 1.0-mode.   In particular,
+   * do not (automatically) sent "Connection" headers and always
+   * close the connection after generating the response.
+   */
+  MHD_RF_HTTP_VERSION_1_0_ONLY = 1
+
+};
+
+
+/**
+ * MHD options (for future extensions).
+ */
+enum MHD_ResponseOptions
+{
+  /**
+   * End of the list of options.
+   */
+  MHD_RO_END = 0
+};
+
+
+/**
+ * Set special flags and options for a response.
+ *
+ * @param response the response to modify
+ * @param flags to set for the response
+ * @param ... #MHD_RO_END terminated list of options
+ * @return #MHD_YES on success, #MHD_NO on error
+ */
+int
+MHD_set_response_options (struct MHD_Response *response,
+                          enum MHD_ResponseFlags flags,
+                          ...);
+
+
 /**
  * Create a response object.  The response object can be extended with
  * header information and then be used any number of times.

+ 2 - 2
src/include/platform_interface.h

@@ -13,12 +13,12 @@
   Lesser General Public License for more details.
 
   You should have received a copy of the GNU Lesser General Public
-  License along with this library. 
+  License along with this library.
   If not, see <http://www.gnu.org/licenses/>.
 */
 
 /**
- * @file include/platfrom_interface.h
+ * @file include/platform_interface.h
  * @brief  internal platform abstraction functions
  * @author Karlson2k (Evgeny Grin)
  */

+ 2 - 2
src/include/w32functions.h

@@ -13,12 +13,12 @@
   Lesser General Public License for more details.
 
   You should have received a copy of the GNU Lesser General Public
-  License along with this library. 
+  License along with this library.
   If not, see <http://www.gnu.org/licenses/>.
 */
 
 /**
- * @file platform/w32functions.h
+ * @file include/w32functions.h
  * @brief  internal functions for W32 systems
  * @author Karlson2k (Evgeny Grin)
  */

+ 7 - 1
src/microhttpd/connection.c

@@ -528,6 +528,9 @@ keepalive_possible (struct MHD_Connection *connection)
 
   if (NULL == connection->version)
     return MHD_NO;
+  if ( (NULL != connection->response) &&
+       (0 != (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
+    return MHD_NO;
   end = MHD_lookup_connection_value (connection,
                                      MHD_HEADER_KIND,
                                      MHD_HTTP_HEADER_CONNECTION);
@@ -596,6 +599,7 @@ add_extra_headers (struct MHD_Connection *connection)
 	  /* 'close' header doesn't exist yet, see if we need to add one;
 	     if the client asked for a close, no need to start chunk'ing */
           if ( (NULL == client_close) &&
+               (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) &&
                (MHD_YES == keepalive_possible (connection)) &&
                (0 == strcasecmp (connection->version,
                                  MHD_HTTP_VERSION_1_1)) )
@@ -662,13 +666,15 @@ add_extra_headers (struct MHD_Connection *connection)
 				   MHD_HTTP_HEADER_CONTENT_LENGTH, buf);
 	}
     }
-  if (MHD_YES == add_close)
+  if ( (MHD_YES == add_close) &&
+       (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) )
     MHD_add_response_header (connection->response,
 			     MHD_HTTP_HEADER_CONNECTION,
                              "close");
   if ( (NULL == have_keepalive) &&
        (NULL == have_close) &&
        (MHD_NO == add_close) &&
+       (0 == (connection->response->flags & MHD_RF_HTTP_VERSION_1_0_ONLY) ) &&
        (MHD_YES == keepalive_possible (connection)) )
     MHD_add_response_header (connection->response,
 			     MHD_HTTP_HEADER_CONNECTION,

+ 7 - 0
src/microhttpd/internal.c

@@ -160,6 +160,13 @@ MHD_http_unescape (void *cls,
 }
 
 
+/**
+ * Equivalent to time(NULL) but tries to use some sort of monotonic
+ * clock that isn't affected by someone setting the system real time
+ * clock.
+ *
+ * @return 'current' time
+ */
 time_t
 MHD_monotonic_time (void)
 {

+ 16 - 9
src/microhttpd/internal.h

@@ -266,8 +266,8 @@ struct MHD_Response
   char *data;
 
   /**
-   * Closure to give to the content reader
-   * free callback.
+   * Closure to give to the content reader @e crc
+   * and content reader free callback @crfc.
    */
   void *crc_cls;
 
@@ -284,8 +284,8 @@ struct MHD_Response
   MHD_ContentReaderFreeCallback crfc;
 
   /**
-   * Mutex to synchronize access to data/size and
-   * reference counts.
+   * Mutex to synchronize access to @e data, @e size and
+   * @e reference_count.
    */
   MHD_mutex_ mutex;
 
@@ -296,22 +296,23 @@ struct MHD_Response
 
   /**
    * At what offset in the stream is the
-   * beginning of data located?
+   * beginning of @e data located?
    */
   uint64_t data_start;
 
   /**
-   * Offset to start reading from when using 'fd'.
+   * Offset to start reading from when using @e fd.
    */
   off_t fd_off;
 
   /**
-   * Size of data.
+   * Number of bytes ready in @e data (buffer may be larger
+   * than what is filled with payload).
    */
   size_t data_size;
 
   /**
-   * Size of the data buffer.
+   * Size of the data buffer @e data.
    */
   size_t data_buffer_size;
 
@@ -326,6 +327,11 @@ struct MHD_Response
    */
   int fd;
 
+  /**
+   * Flags set for the MHD response.
+   */
+  enum MHD_ResponseFlags flags;
+
 };
 
 
@@ -1386,6 +1392,7 @@ struct MHD_Daemon
  *
  * @return 'current' time
  */
-time_t MHD_monotonic_time(void);
+time_t
+MHD_monotonic_time(void);
 
 #endif

+ 34 - 0
src/microhttpd/response.c

@@ -265,6 +265,40 @@ MHD_create_response_from_callback (uint64_t size,
 }
 
 
+/**
+ * Set special flags and options for a response.
+ *
+ * @param response the response to modify
+ * @param flags to set for the response
+ * @param ... #MHD_RO_END terminated list of options
+ * @return #MHD_YES on success, #MHD_NO on error
+ */
+int
+MHD_set_response_options (struct MHD_Response *response,
+                          enum MHD_ResponseFlags flags,
+                          ...)
+{
+  va_list ap;
+  int ret;
+  enum MHD_ResponseOptions ro;
+
+  ret = MHD_YES;
+  response->flags = flags;
+  va_start (ap, flags);
+  while (MHD_RO_END != (ro = va_arg (ap, enum MHD_ResponseOptions)))
+  {
+    switch (ro)
+    {
+    default:
+      ret = MHD_NO;
+      break;
+    }
+  }
+  va_end (ap);
+  return ret;
+}
+
+
 /**
  * Given a file descriptor, read data from the file
  * to generate the response.