gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r5617 - in libmicrohttpd: . src/daemon src/include


From: gnunet
Subject: [GNUnet-SVN] r5617 - in libmicrohttpd: . src/daemon src/include
Date: Sat, 8 Sep 2007 21:56:10 -0600 (MDT)

Author: grothoff
Date: 2007-09-08 21:56:10 -0600 (Sat, 08 Sep 2007)
New Revision: 5617

Modified:
   libmicrohttpd/ChangeLog
   libmicrohttpd/README
   libmicrohttpd/configure.ac
   libmicrohttpd/src/daemon/Makefile.am
   libmicrohttpd/src/daemon/connection.c
   libmicrohttpd/src/daemon/daemon.c
   libmicrohttpd/src/daemon/daemontest.c
   libmicrohttpd/src/daemon/daemontest_get.c
   libmicrohttpd/src/daemon/daemontest_large_put.c
   libmicrohttpd/src/daemon/daemontest_long_header.c
   libmicrohttpd/src/daemon/daemontest_post.c
   libmicrohttpd/src/daemon/daemontest_put.c
   libmicrohttpd/src/daemon/fileserver_example.c
   libmicrohttpd/src/daemon/internal.c
   libmicrohttpd/src/daemon/internal.h
   libmicrohttpd/src/daemon/minimal_example.c
   libmicrohttpd/src/include/microhttpd.h
Log:
incremental post processing API and implementation

Modified: libmicrohttpd/ChangeLog
===================================================================
--- libmicrohttpd/ChangeLog     2007-09-09 00:10:05 UTC (rev 5616)
+++ libmicrohttpd/ChangeLog     2007-09-09 03:56:10 UTC (rev 5617)
@@ -1,3 +1,11 @@
+Sat Sep  8 21:54:04 MDT 2007
+        Extended API to allow for incremental POST 
+        processing.  The new API is binary-compatible
+        as long as the app does not handle POSTs, but
+        since that maybe the case, we're strictly speaking
+        breaking backwards compatibility (since url-encoded
+        POST data is no longer obtained the same way). - CG
+
 Thu Aug 30 00:59:24 MDT 2007
         Improving API to allow clients to associate state 
          with a connection and to be notified about request

Modified: libmicrohttpd/README
===================================================================
--- libmicrohttpd/README        2007-09-09 00:10:05 UTC (rev 5616)
+++ libmicrohttpd/README        2007-09-09 03:56:10 UTC (rev 5617)
@@ -18,17 +18,8 @@
 
 For POST:
 =========
-- find better way to handle POST data that does not fit into memory (#1221, 
API, TEST)
 - add support to decode multipart/form-data (#1221, TEST)
 
-API Improvements:
-=================
-- allow clients to associate a void * with each connection (for easier client 
state
-  management)
-- allow clients to register callback to be invoked when connection is
-  timed out or otherwise completed / aborted / closed (for easier client
-  state clean up)
-
 For SSL:
 ========
 microhttpd.h:

Modified: libmicrohttpd/configure.ac
===================================================================
--- libmicrohttpd/configure.ac  2007-09-09 00:10:05 UTC (rev 5616)
+++ libmicrohttpd/configure.ac  2007-09-09 03:56:10 UTC (rev 5617)
@@ -21,8 +21,8 @@
 #
 #
 AC_PREREQ(2.57)
-AC_INIT([libmicrohttpd], [0.0.3],address@hidden)
-AM_INIT_AUTOMAKE([libmicrohttpd], [0.0.3])
+AC_INIT([libmicrohttpd], [0.1.0],address@hidden)
+AM_INIT_AUTOMAKE([libmicrohttpd], [0.1.0])
 AM_CONFIG_HEADER([config.h])
 
 AH_TOP([#define _GNU_SOURCE  1])

Modified: libmicrohttpd/src/daemon/Makefile.am
===================================================================
--- libmicrohttpd/src/daemon/Makefile.am        2007-09-09 00:10:05 UTC (rev 
5616)
+++ libmicrohttpd/src/daemon/Makefile.am        2007-09-09 03:56:10 UTC (rev 
5617)
@@ -6,13 +6,14 @@
   libmicrohttpd.la
 
 libmicrohttpd_la_LDFLAGS = \
-  -export-dynamic -version-info 1:0:0 
+  -export-dynamic -version-info 2:0:0 
 libmicrohttpd_la_SOURCES = \
   connection.c connection.h \
   daemon.c  \
   internal.c internal.h \
   memorypool.c memorypool.h \
   plibc.h \
+  postprocessor.c \
   response.c response.h 
 
 # example programs

Modified: libmicrohttpd/src/daemon/connection.c
===================================================================
--- libmicrohttpd/src/daemon/connection.c       2007-09-09 00:10:05 UTC (rev 
5616)
+++ libmicrohttpd/src/daemon/connection.c       2007-09-09 03:56:10 UTC (rev 
5617)
@@ -57,7 +57,7 @@
 /**
  * Add extra debug messages with reasons for closing connections
  * (non-error reasons).
- */ 
+ */
 #define DEBUG_CLOSE 0
 
 
@@ -184,17 +184,17 @@
  * A serious error occured, close the
  * connection (and notify the application).
  */
-static void 
-connection_close_error(struct MHD_Connection * connection) 
+static void
+connection_close_error (struct MHD_Connection *connection)
 {
   SHUTDOWN (connection->socket_fd, SHUT_RDWR);
   CLOSE (connection->socket_fd);
   connection->socket_fd = -1;
-  if (connection->daemon->notify_completed != NULL) 
-    
connection->daemon->notify_completed(connection->daemon->notify_completed_cls,
-                                        connection,
-                                        &connection->client_context,
-                                        MHD_REQUEST_TERMINATED_WITH_ERROR);
+  if (connection->daemon->notify_completed != NULL)
+    connection->daemon->notify_completed (connection->daemon->
+                                          notify_completed_cls, connection,
+                                          &connection->client_context,
+                                          MHD_REQUEST_TERMINATED_WITH_ERROR);
 }
 
 /**
@@ -222,11 +222,10 @@
     {
       /* end of message, signal other side by closing! */
 #if DEBUG_CLOSE
-      MHD_DLOG (connection->daemon,
-               "Closing connection (end of response)\n");
+      MHD_DLOG (connection->daemon, "Closing connection (end of response)\n");
 #endif
       response->total_size = connection->messagePos;
-      connection_close_error(connection);
+      connection_close_error (connection);
       return MHD_NO;
     }
   response->data_start = connection->messagePos;
@@ -281,7 +280,6 @@
     {
       if ((connection->read_close == MHD_NO) &&
           ((connection->headersReceived == 1) &&
-           (connection->post_processed == MHD_NO) &&
            (connection->readLoc == connection->read_buffer_size)))
         {
           /* try growing the read buffer, just in case */
@@ -297,7 +295,7 @@
               connection->read_buffer_size =
                 connection->read_buffer_size * 2 + MHD_BUF_INC_SIZE;
               FD_SET (fd, read_fd_set);
-             if (fd > *max_fd)
+              if (fd > *max_fd)
                 *max_fd = fd;
             }
         }
@@ -430,29 +428,6 @@
 }
 
 /**
- * Process escape sequences ('+'=space, %HH)
- */
-static void
-MHD_http_unescape (char *val)
-{
-  char *esc;
-  unsigned int num;
-
-  while (NULL != (esc = strstr (val, "+")))
-    *esc = ' ';
-  while (NULL != (esc = strstr (val, "%")))
-    {
-      if ((1 == sscanf (&esc[1],
-                        "%2x", &num)) || (1 == sscanf (&esc[1], "%2X", &num)))
-        {
-          esc[0] = (unsigned char) num;
-          memmove (&esc[1], &esc[3], strlen (&esc[3]));
-        }
-      val = esc + 1;
-    }
-}
-
-/**
  * @return MHD_NO on failure (out of memory), MHD_YES for success
  */
 static int
@@ -615,10 +590,11 @@
   const char *clen;
   const char *end;
   unsigned long long cval;
-  struct MHD_Response * response;
+  struct MHD_Response *response;
 
   if (connection->bodyReceived == 1)
     abort ();
+  colon = NULL; /* make gcc happy */
   last = NULL;
   while (NULL != (line = MHD_get_next_header_line (connection)))
     {
@@ -707,29 +683,28 @@
                  this request */
               connection->read_close = MHD_YES;
             }
-         
-         if ( (0 != (MHD_USE_PEDANTIC_CHECKS & connection->daemon->options)) &&
-              (NULL != connection->version) &&
-              (0 == strcasecmp(MHD_HTTP_VERSION_1_1,
-                               connection->version)) &&
-              (NULL == MHD_lookup_connection_value(connection,
-                                                   MHD_HEADER_KIND,
-                                                   MHD_HTTP_HEADER_HOST)) ) {
-           /* die, http 1.1 request without host and we are pedantic */
-           connection->bodyReceived = MHD_YES;
-           connection->read_close = MHD_YES;
-           MHD_DLOG (connection->daemon,
-                     "Received `%s' request without `%s' header.\n",
-                     MHD_HTTP_VERSION_1_1,
-                     MHD_HTTP_HEADER_HOST);
-           response = MHD_create_response_from_data (strlen 
(REQUEST_LACKS_HOST),
-                                                     REQUEST_LACKS_HOST, 
MHD_NO, MHD_NO);
-           MHD_queue_response (connection,
-                               MHD_HTTP_BAD_REQUEST,
-                               response);
-           MHD_destroy_response (response);
-         }
-                             
+
+          if ((0 != (MHD_USE_PEDANTIC_CHECKS & connection->daemon->options))
+              && (NULL != connection->version)
+              && (0 == strcasecmp (MHD_HTTP_VERSION_1_1, connection->version))
+              && (NULL ==
+                  MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
+                                               MHD_HTTP_HEADER_HOST)))
+            {
+              /* die, http 1.1 request without host and we are pedantic */
+              connection->bodyReceived = MHD_YES;
+              connection->read_close = MHD_YES;
+              MHD_DLOG (connection->daemon,
+                        "Received `%s' request without `%s' header.\n",
+                        MHD_HTTP_VERSION_1_1, MHD_HTTP_HEADER_HOST);
+              response =
+                MHD_create_response_from_data (strlen (REQUEST_LACKS_HOST),
+                                               REQUEST_LACKS_HOST, MHD_NO,
+                                               MHD_NO);
+              MHD_queue_response (connection, MHD_HTTP_BAD_REQUEST, response);
+              MHD_destroy_response (response);
+            }
+
           break;
         }
       /* line should be normal header line, find colon */
@@ -761,8 +736,8 @@
   return;
 DIE:
   MHD_DLOG (connection->daemon,
-           "Closing connection (problem parsing headers)\n");
-  connection_close_error(connection);
+            "Closing connection (problem parsing headers)\n");
+  connection_close_error (connection);
 }
 
 
@@ -784,109 +759,8 @@
   return &connection->daemon->default_handler;
 }
 
-/**
- * Test if we are able to process the POST data.
- * This depends on available memory (enough to load
- * all of the POST data into the pool) and the
- * content encoding of the POST data.  And of course,
- * this requires that the request is actually a
- * POST request.
- *
- * @return MHD_YES if so
- */
-static int
-MHD_test_post_data (struct MHD_Connection *connection)
-{
-  const char *encoding;
-  void *buf;
 
-  if ((connection->method == NULL) ||
-      (connection->response != NULL) ||
-      (0 != strcasecmp (connection->method, MHD_HTTP_METHOD_POST)))
-    return MHD_NO;
-  encoding = MHD_lookup_connection_value (connection,
-                                          MHD_HEADER_KIND,
-                                          MHD_HTTP_HEADER_CONTENT_TYPE);
-  if (encoding == NULL)
-    return MHD_NO;
-  if ((0 == strcasecmp (MHD_HTTP_POST_ENCODING_FORM_URLENCODED,
-                        encoding)) && (connection->uploadSize != -1))
-    {
-      buf = MHD_pool_reallocate (connection->pool,
-                                 connection->read_buffer,
-                                 (connection->read_buffer == NULL) ? 0 : 
connection->read_buffer_size + 1,
-                                 connection->uploadSize + 1);
-      if (buf == NULL)
-        return MHD_NO;
-      connection->read_buffer_size = connection->uploadSize;
-      connection->read_buffer = buf;
-      return MHD_YES;
-    }
-  return MHD_NO;
-}
-
 /**
- * Process the POST data here (adding to headers).
- *
- * Needs to first check POST encoding and then do
- * the right thing (TM).  The POST data is in the
- * connection's post_data buffer between the postPos
- * and postLoc offsets.  The POST message maybe
- * incomplete.  The existing buffer (allocated from
- * the pool) can be used and modified but must then
- * be properly removed from the struct.
- *
- * @return MHD_YES on success, MHD_NO on error (i.e. out of
- *         memory).
- */
-static int
-MHD_parse_post_data (struct MHD_Connection *connection)
-{
-  const char *encoding;
-  int ret;
-
-  encoding = MHD_lookup_connection_value (connection,
-                                          MHD_HEADER_KIND,
-                                          MHD_HTTP_HEADER_CONTENT_TYPE);
-  if (encoding == NULL)
-    return MHD_NO;
-  if (0 == strcasecmp (MHD_HTTP_POST_ENCODING_FORM_URLENCODED, encoding))
-    {
-      /* add 0-termination, that's why the actual buffer size 
-        is always 1 more than what is actually required for the data! */
-      connection->read_buffer[connection->readLoc] = '\0';
-      ret = parse_arguments (MHD_POSTDATA_KIND,
-                             connection, connection->read_buffer);
-      /* invalidate read buffer for other uses --
-         in particular, do not give it to the
-         client; if this were to be needed, we would
-         have to make a copy, which would double memory
-         requirements */
-      connection->read_buffer_size = 0;
-      connection->readLoc = 0;
-      connection->uploadSize = 0;
-      connection->read_buffer = NULL;
-      return ret;
-    }
-  if (0 == strcasecmp (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA, encoding))
-    {
-      /* this code should never been reached right now,
-         since the test_post_data function would already
-         return MHD_NO; code is here only for future
-         extensions... */
-      /* see http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4 */
-      MHD_DLOG (connection->daemon,
-                "Unsupported multipart encoding of POST data specified, not 
processing POST data.\n");
-      return MHD_NO;
-    }
-  /* this should never be reached, just here for
-     error checking */
-  MHD_DLOG (connection->daemon,
-            "Unknown encoding of POST data specified, not processing POST 
data.\n");
-  return MHD_NO;
-}
-
-/**
  * Call the handler of the application for this
  * connection.
  */
@@ -908,12 +782,12 @@
                         connection->method,
                         connection->version,
                         connection->read_buffer, &processed,
-                       &connection->client_context))
+                        &connection->client_context))
     {
       /* serios internal error, close connection */
       MHD_DLOG (connection->daemon,
                 "Internal application error, closing connection.\n");
-      connection_close_error(connection);
+      connection_close_error (connection);
       return;
     }
   /* dh left "processed" bytes in buffer for next time... */
@@ -929,10 +803,11 @@
     {
       connection->bodyReceived = 1;
       if (connection->read_buffer != NULL)
-       MHD_pool_reallocate(connection->pool,
-                           connection->read_buffer,
-                           (connection->read_buffer == NULL) ? 0 : 
connection->read_buffer_size + 1,
-                           0);
+        MHD_pool_reallocate (connection->pool,
+                             connection->read_buffer,
+                             (connection->read_buffer ==
+                              NULL) ? 0 : connection->read_buffer_size + 1,
+                             0);
       connection->readLoc = 0;
       connection->read_buffer_size = 0;
       connection->read_buffer = NULL;
@@ -957,7 +832,7 @@
   if (connection->pool == NULL)
     {
       MHD_DLOG (connection->daemon, "Failed to create memory pool!\n");
-      connection_close_error(connection);
+      connection_close_error (connection);
       return MHD_NO;
     }
   if ((connection->readLoc >= connection->read_buffer_size) &&
@@ -995,15 +870,14 @@
         return MHD_NO;
       MHD_DLOG (connection->daemon,
                 "Failed to receive data: %s\n", STRERROR (errno));
-      connection_close_error(connection);
+      connection_close_error (connection);
       return MHD_YES;
     }
   if (bytes_read == 0)
     {
       /* other side closed connection */
       connection->read_close = MHD_YES;
-      if ( (connection->headersReceived == 1) &&
-          (connection->readLoc > 0) )
+      if ((connection->headersReceived == 1) && (connection->readLoc > 0))
         MHD_call_connection_handler (connection);
 #if DEBUG_CLOSE
       MHD_DLOG (connection->daemon,
@@ -1014,24 +888,9 @@
     }
   connection->readLoc += bytes_read;
   if (connection->headersReceived == 0)
-    {
-      MHD_parse_connection_headers (connection);
-      if (connection->headersReceived == 1)
-        {
-          connection->post_processed = MHD_test_post_data (connection);
-        }
-    }
-  if (connection->headersReceived == 1)
-    {
-      if ((connection->post_processed == MHD_YES) &&
-          (connection->uploadSize == connection->readLoc))
-        if (MHD_NO == MHD_parse_post_data (connection))
-          connection->post_processed = MHD_NO;
-      if (((connection->post_processed == MHD_NO) ||
-           (connection->read_buffer_size == connection->readLoc)) &&
-          (connection->method != NULL))
-        MHD_call_connection_handler (connection);
-    }
+    MHD_parse_connection_headers (connection);
+  if ((connection->headersReceived == 1) && (connection->method != NULL))
+    MHD_call_connection_handler (connection);
   return MHD_YES;
 }
 
@@ -1171,14 +1030,13 @@
             return MHD_YES;
           MHD_DLOG (connection->daemon,
                     "Failed to send data: %s\n", STRERROR (errno));
-         connection_close_error(connection);
+          connection_close_error (connection);
           return MHD_YES;
         }
 #if DEBUG_SEND_DATA
-      fprintf(stderr,
-             "Sent 100 continue response: `%.*s'\n",
-             ret,
-             &HTTP_100_CONTINUE[connection->continuePos]);
+      fprintf (stderr,
+               "Sent 100 continue response: `%.*s'\n",
+               ret, &HTTP_100_CONTINUE[connection->continuePos]);
 #endif
       connection->continuePos += ret;
       return MHD_YES;
@@ -1195,9 +1053,9 @@
           (MHD_NO == MHD_build_header_response (connection)))
         {
           /* oops - close! */
-         MHD_DLOG (connection->daemon, 
-                   "Closing connection (failed to create response header)\n");
-         connection_close_error(connection);
+          MHD_DLOG (connection->daemon,
+                    "Closing connection (failed to create response header)\n");
+          connection_close_error (connection);
           return MHD_NO;
         }
       ret = SEND (connection->socket_fd,
@@ -1209,14 +1067,13 @@
             return MHD_YES;
           MHD_DLOG (connection->daemon,
                     "Failed to send data: %s\n", STRERROR (errno));
-         connection_close_error(connection);
+          connection_close_error (connection);
           return MHD_YES;
         }
 #if DEBUG_SEND_DATA
-      fprintf(stderr,
-             "Sent HEADER response: `%.*s'\n",
-             ret,
-             &connection->write_buffer[connection->writePos]);
+      fprintf (stderr,
+               "Sent HEADER response: `%.*s'\n",
+               ret, &connection->write_buffer[connection->writePos]);
 #endif
       connection->writePos += ret;
       if (connection->writeLoc == connection->writePos)
@@ -1259,14 +1116,14 @@
         return MHD_YES;
       MHD_DLOG (connection->daemon,
                 "Failed to send data: %s\n", STRERROR (errno));
-      connection_close_error(connection);
+      connection_close_error (connection);
       return MHD_YES;
     }
 #if DEBUG_SEND_DATA
-  fprintf(stderr,
-         "Sent DATA response: `%.*s'\n",
-         ret,
-         &response->data[connection->messagePos - response->data_start]);
+  fprintf (stderr,
+           "Sent DATA response: `%.*s'\n",
+           ret,
+           &response->data[connection->messagePos - response->data_start]);
 #endif
   connection->messagePos += ret;
   if (connection->messagePos > response->total_size)
@@ -1277,11 +1134,12 @@
           (connection->headersReceived == 0))
         abort ();               /* internal error */
       MHD_destroy_response (response);
-      if (connection->daemon->notify_completed != NULL) 
-       
connection->daemon->notify_completed(connection->daemon->notify_completed_cls,
-                                            connection,
-                                            &connection->client_context,
-                                            
MHD_REQUEST_TERMINATED_COMPLETED_OK);      
+      if (connection->daemon->notify_completed != NULL)
+        connection->daemon->notify_completed (connection->daemon->
+                                              notify_completed_cls,
+                                              connection,
+                                              &connection->client_context,
+                                              
MHD_REQUEST_TERMINATED_COMPLETED_OK);
       connection->client_context = NULL;
       connection->continuePos = 0;
       connection->responseCode = 0;
@@ -1297,14 +1155,15 @@
           (0 != strcasecmp (MHD_HTTP_VERSION_1_1, connection->version)))
         {
           /* closed for reading => close for good! */
-          if (connection->socket_fd != -1) {
+          if (connection->socket_fd != -1)
+            {
 #if DEBUG_CLOSE
-           MHD_DLOG (connection->daemon,
-                     "Closing connection (http 1.0 or end-of-stream for 
unknown content length)\n");
+              MHD_DLOG (connection->daemon,
+                        "Closing connection (http 1.0 or end-of-stream for 
unknown content length)\n");
 #endif
-           SHUTDOWN (connection->socket_fd, SHUT_RDWR);
-            CLOSE (connection->socket_fd);
-         }
+              SHUTDOWN (connection->socket_fd, SHUT_RDWR);
+              CLOSE (connection->socket_fd);
+            }
           connection->socket_fd = -1;
         }
       connection->version = NULL;

Modified: libmicrohttpd/src/daemon/daemon.c
===================================================================
--- libmicrohttpd/src/daemon/daemon.c   2007-09-09 00:10:05 UTC (rev 5616)
+++ libmicrohttpd/src/daemon/daemon.c   2007-09-09 03:56:10 UTC (rev 5617)
@@ -225,8 +225,8 @@
   if (con->socket_fd != -1)
     {
 #if DEBUG_CLOSE
-      MHD_DLOG (con->daemon, 
-               "Processing thread terminating, closing connection\n");
+      MHD_DLOG (con->daemon,
+                "Processing thread terminating, closing connection\n");
 #endif
       SHUTDOWN (con->socket_fd, SHUT_RDWR);
       CLOSE (con->socket_fd);
@@ -259,10 +259,11 @@
   if ((s < 0) || (addrlen <= 0))
     {
       MHD_DLOG (daemon, "Error accepting connection: %s\n", STRERROR (errno));
-      if (s != -1) {
-       SHUTDOWN (s, SHUT_RDWR);
-        CLOSE (s);              /* just in case */
-      }
+      if (s != -1)
+        {
+          SHUTDOWN (s, SHUT_RDWR);
+          CLOSE (s);            /* just in case */
+        }
       return MHD_NO;
     }
   if (daemon->max_connections == 0)
@@ -278,8 +279,7 @@
       (MHD_NO == daemon->apc (daemon->apc_cls, addr, addrlen)))
     {
 #if DEBUG_CLOSE
-      MHD_DLOG (daemon, 
-               "Connection rejected, closing connection\n");
+      MHD_DLOG (daemon, "Connection rejected, closing connection\n");
 #endif
       SHUTDOWN (s, SHUT_RDWR);
       CLOSE (s);
@@ -357,17 +357,16 @@
       if ((pos->last_activity < timeout) && (pos->socket_fd != -1))
         {
 #if DEBUG_CLOSE
-         MHD_DLOG (daemon, 
-                   "Connection timed out, closing connection\n");
+          MHD_DLOG (daemon, "Connection timed out, closing connection\n");
 #endif
-         SHUTDOWN (pos->socket_fd, SHUT_RDWR);
+          SHUTDOWN (pos->socket_fd, SHUT_RDWR);
           CLOSE (pos->socket_fd);
           pos->socket_fd = -1;
-         if (pos->daemon->notify_completed != NULL) 
-           pos->daemon->notify_completed(pos->daemon->notify_completed_cls,
-                                         pos,
-                                         &pos->client_context,
-                                         
MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
+          if (pos->daemon->notify_completed != NULL)
+            pos->daemon->notify_completed (pos->daemon->notify_completed_cls,
+                                           pos,
+                                           &pos->client_context,
+                                           
MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
         }
       if (pos->socket_fd == -1)
         {
@@ -472,19 +471,19 @@
   FD_ZERO (&ws);
   FD_ZERO (&es);
   max = 0;
-  
+
   if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
     {
       /* single-threaded, go over everything */
       if (MHD_NO == MHD_get_fdset (daemon, &rs, &ws, &es, &max))
-       return MHD_NO;
+        return MHD_NO;
     }
   else
     {
       /* accept only, have one thread per connection */
       max = daemon->socket_fd;
       if (max == -1)
-       return MHD_NO;
+        return MHD_NO;
       FD_SET (max, &rs);
     }
   if (may_block == MHD_NO)
@@ -496,21 +495,20 @@
     {
       /* ltimeout is in ms */
       if (MHD_YES == MHD_get_timeout (daemon, &ltimeout))
-       {
-         timeout.tv_usec = (ltimeout % 1000) * 1000;
-         timeout.tv_sec = ltimeout / 1000;
-         may_block = MHD_NO;
-       }
+        {
+          timeout.tv_usec = (ltimeout % 1000) * 1000;
+          timeout.tv_sec = ltimeout / 1000;
+          may_block = MHD_NO;
+        }
     }
   num_ready = SELECT (max + 1,
-                     &rs, &ws, &es,
-                     may_block == MHD_NO ? &timeout : NULL);
+                      &rs, &ws, &es, may_block == MHD_NO ? &timeout : NULL);
   if (daemon->shutdown == MHD_YES)
     return MHD_NO;
   if (num_ready < 0)
     {
       if (errno == EINTR)
-       return MHD_YES;
+        return MHD_YES;
       MHD_DLOG (daemon, "Select failed: %s\n", STRERROR (errno));
       return MHD_NO;
     }
@@ -525,23 +523,23 @@
       now = time (NULL);
       pos = daemon->connections;
       while (pos != NULL)
-       {
-         ds = pos->socket_fd;
-         if (ds != -1)
-           {
-             if (FD_ISSET (ds, &rs))
-               {
-                 pos->last_activity = now;
-                 MHD_connection_handle_read (pos);
-               }
-             if (FD_ISSET (ds, &ws))
-               {
-                 pos->last_activity = now;
-                 MHD_connection_handle_write (pos);
-               }
-           }
-         pos = pos->next;
-       }
+        {
+          ds = pos->socket_fd;
+          if (ds != -1)
+            {
+              if (FD_ISSET (ds, &rs))
+                {
+                  pos->last_activity = now;
+                  MHD_connection_handle_read (pos);
+                }
+              if (FD_ISSET (ds, &ws))
+                {
+                  pos->last_activity = now;
+                  MHD_connection_handle_write (pos);
+                }
+            }
+          pos = pos->next;
+        }
     }
   return MHD_YES;
 }
@@ -694,10 +692,11 @@
         case MHD_OPTION_CONNECTION_TIMEOUT:
           retVal->connection_timeout = va_arg (ap, unsigned int);
           break;
-       case MHD_OPTION_NOTIFY_COMPLETED:
-         retVal->notify_completed = va_arg(ap, MHD_RequestCompletedCallback);
-         retVal->notify_completed_cls = va_arg(ap, void *);
-         break;
+        case MHD_OPTION_NOTIFY_COMPLETED:
+          retVal->notify_completed =
+            va_arg (ap, MHD_RequestCompletedCallback);
+          retVal->notify_completed_cls = va_arg (ap, void *);
+          break;
         default:
           fprintf (stderr,
                    "Invalid MHD_OPTION argument! (Did you terminate the list 
with MHD_OPTION_END?)\n");
@@ -733,8 +732,7 @@
   fd = daemon->socket_fd;
   daemon->socket_fd = -1;
 #if DEBUG_CLOSE
-  MHD_DLOG (daemon, 
-           "MHD shutdown, closing listen socket\n");
+  MHD_DLOG (daemon, "MHD shutdown, closing listen socket\n");
 #endif
   CLOSE (fd);
   if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
@@ -748,16 +746,15 @@
       if (-1 != daemon->connections->socket_fd)
         {
 #if DEBUG_CLOSE
-         MHD_DLOG (daemon, 
-                   "MHD shutdown, closing active connections\n");
+          MHD_DLOG (daemon, "MHD shutdown, closing active connections\n");
 #endif
-         if (daemon->notify_completed != NULL) 
-           daemon->notify_completed(daemon->notify_completed_cls,
-                                    daemon->connections,
-                                    &daemon->connections->client_context,
-                                    MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
-         SHUTDOWN (daemon->connections->socket_fd, SHUT_RDWR);
-         CLOSE (daemon->connections->socket_fd);
+          if (daemon->notify_completed != NULL)
+            daemon->notify_completed (daemon->notify_completed_cls,
+                                      daemon->connections,
+                                      &daemon->connections->client_context,
+                                      MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
+          SHUTDOWN (daemon->connections->socket_fd, SHUT_RDWR);
+          CLOSE (daemon->connections->socket_fd);
           daemon->connections->socket_fd = -1;
         }
       MHD_cleanup_connections (daemon);

Modified: libmicrohttpd/src/daemon/daemontest.c
===================================================================
--- libmicrohttpd/src/daemon/daemontest.c       2007-09-09 00:10:05 UTC (rev 
5616)
+++ libmicrohttpd/src/daemon/daemontest.c       2007-09-09 03:56:10 UTC (rev 
5617)
@@ -65,7 +65,7 @@
              const char *method,
              const char *version,
              const char *upload_data, unsigned int *upload_data_size,
-            void ** unused)
+             void **unused)
 {
   return MHD_NO;
 }

Modified: libmicrohttpd/src/daemon/daemontest_get.c
===================================================================
--- libmicrohttpd/src/daemon/daemontest_get.c   2007-09-09 00:10:05 UTC (rev 
5616)
+++ libmicrohttpd/src/daemon/daemontest_get.c   2007-09-09 03:56:10 UTC (rev 
5617)
@@ -64,7 +64,7 @@
           const char *method,
           const char *version,
           const char *upload_data, unsigned int *upload_data_size,
-         void ** unused)
+          void **unused)
 {
   const char *me = cls;
   struct MHD_Response *response;

Modified: libmicrohttpd/src/daemon/daemontest_large_put.c
===================================================================
--- libmicrohttpd/src/daemon/daemontest_large_put.c     2007-09-09 00:10:05 UTC 
(rev 5616)
+++ libmicrohttpd/src/daemon/daemontest_large_put.c     2007-09-09 03:56:10 UTC 
(rev 5617)
@@ -86,7 +86,7 @@
           const char *method,
           const char *version,
           const char *upload_data, unsigned int *upload_data_size,
-         void ** unused)
+          void **unused)
 {
   int *done = cls;
   struct MHD_Response *response;

Modified: libmicrohttpd/src/daemon/daemontest_long_header.c
===================================================================
--- libmicrohttpd/src/daemon/daemontest_long_header.c   2007-09-09 00:10:05 UTC 
(rev 5616)
+++ libmicrohttpd/src/daemon/daemontest_long_header.c   2007-09-09 03:56:10 UTC 
(rev 5617)
@@ -70,7 +70,7 @@
           const char *method,
           const char *version,
           const char *upload_data, unsigned int *upload_data_size,
-         void ** unused)
+          void **unused)
 {
   const char *me = cls;
   struct MHD_Response *response;

Modified: libmicrohttpd/src/daemon/daemontest_post.c
===================================================================
--- libmicrohttpd/src/daemon/daemontest_post.c  2007-09-09 00:10:05 UTC (rev 
5616)
+++ libmicrohttpd/src/daemon/daemontest_post.c  2007-09-09 03:56:10 UTC (rev 
5617)
@@ -63,38 +63,66 @@
   return size * nmemb;
 }
 
+/**
+ * Note that this post_iterator is not perfect
+ * in that it fails to support incremental processing.
+ * (to be fixed in the future)
+ */
 static int
+post_iterator (void *cls,
+               enum MHD_ValueKind kind,
+               const char *key, const char *value, size_t off, size_t size)
+{
+  int *eok = cls;
+
+  if ((0 == strcmp (key, "name")) &&
+      (size == strlen ("daniel")) && (0 == strncmp (value, "daniel", size)))
+    (*eok) |= 1;
+  if ((0 == strcmp (key, "project")) &&
+      (size == strlen ("curl")) && (0 == strncmp (value, "curl", size)))
+    (*eok) |= 2;
+  return MHD_YES;
+}
+
+static int
 ahc_echo (void *cls,
           struct MHD_Connection *connection,
           const char *url,
           const char *method,
           const char *version,
           const char *upload_data, unsigned int *upload_data_size,
-         void ** unused)
+          void **unused)
 {
+  static int eok;
   struct MHD_Response *response;
+  struct MHD_PostProcessor *pp;
   int ret;
-  const char *r1;
-  const char *r2;
 
   if (0 != strcmp ("POST", method))
     {
       printf ("METHOD: %s\n", method);
       return MHD_NO;            /* unexpected method */
     }
-  r1 = MHD_lookup_connection_value (connection, MHD_POSTDATA_KIND, "name");
-  r2 = MHD_lookup_connection_value (connection, MHD_POSTDATA_KIND, "project");
-  if ((r1 != NULL) &&
-      (r2 != NULL) &&
-      (0 == strcmp ("daniel", r1)) && (0 == strcmp ("curl", r2)))
+  pp = *unused;
+  if (pp == NULL)
     {
+      eok = 0;
+      pp = MHD_create_post_processor (connection, 1024, &post_iterator, &eok);
+      *unused = pp;
+    }
+  MHD_post_process (pp, upload_data, *upload_data_size);
+  if ((eok == 3) && (0 == *upload_data_size))
+    {
       response = MHD_create_response_from_data (strlen (url),
                                                 (void *) url,
                                                 MHD_NO, MHD_YES);
       ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
       MHD_destroy_response (response);
-      return MHD_YES;           /* done */
+      MHD_destroy_post_processor (pp);
+      *unused = NULL;
+      return ret;
     }
+  *upload_data_size = 0;
   return MHD_YES;
 }
 

Modified: libmicrohttpd/src/daemon/daemontest_put.c
===================================================================
--- libmicrohttpd/src/daemon/daemontest_put.c   2007-09-09 00:10:05 UTC (rev 
5616)
+++ libmicrohttpd/src/daemon/daemontest_put.c   2007-09-09 03:56:10 UTC (rev 
5617)
@@ -77,7 +77,7 @@
           const char *method,
           const char *version,
           const char *upload_data, unsigned int *upload_data_size,
-         void ** unused)
+          void **unused)
 {
   int *done = cls;
   struct MHD_Response *response;
@@ -363,10 +363,11 @@
   if (0 != curl_global_init (CURL_GLOBAL_WIN32))
     return 2;
   errorCount += testInternalPut ();
-  if (0) {
-    errorCount += testMultithreadedPut ();
-    errorCount += testExternalPut ();
-  }
+  if (0)
+    {
+      errorCount += testMultithreadedPut ();
+      errorCount += testExternalPut ();
+    }
   if (errorCount != 0)
     fprintf (stderr, "Error (code: %u)\n", errorCount);
   curl_global_cleanup ();

Modified: libmicrohttpd/src/daemon/fileserver_example.c
===================================================================
--- libmicrohttpd/src/daemon/fileserver_example.c       2007-09-09 00:10:05 UTC 
(rev 5616)
+++ libmicrohttpd/src/daemon/fileserver_example.c       2007-09-09 03:56:10 UTC 
(rev 5617)
@@ -52,8 +52,7 @@
           const char *url,
           const char *method,
           const char *upload_data,
-          const char *version, unsigned int *upload_data_size,
-         void ** unused)
+          const char *version, unsigned int *upload_data_size, void **unused)
 {
   struct MHD_Response *response;
   int ret;

Modified: libmicrohttpd/src/daemon/internal.c
===================================================================
--- libmicrohttpd/src/daemon/internal.c 2007-09-09 00:10:05 UTC (rev 5616)
+++ libmicrohttpd/src/daemon/internal.c 2007-09-09 03:56:10 UTC (rev 5617)
@@ -42,3 +42,26 @@
   VFPRINTF (stderr, format, va);
   va_end (va);
 }
+
+/**
+ * Process escape sequences ('+'=space, %HH)
+ */
+void
+MHD_http_unescape (char *val)
+{
+  char *esc;
+  unsigned int num;
+
+  while (NULL != (esc = strstr (val, "+")))
+    *esc = ' ';
+  while (NULL != (esc = strstr (val, "%")))
+    {
+      if ((1 == sscanf (&esc[1],
+                        "%2x", &num)) || (1 == sscanf (&esc[1], "%2X", &num)))
+        {
+          esc[0] = (unsigned char) num;
+          memmove (&esc[1], &esc[3], strlen (&esc[3]));
+        }
+      val = esc + 1;
+    }
+}

Modified: libmicrohttpd/src/daemon/internal.h
===================================================================
--- libmicrohttpd/src/daemon/internal.h 2007-09-09 00:10:05 UTC (rev 5616)
+++ libmicrohttpd/src/daemon/internal.h 2007-09-09 03:56:10 UTC (rev 5617)
@@ -65,6 +65,11 @@
  */
 void MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...);
 
+/**
+ * Process escape sequences ('+'=space, %HH).
+ * Updates val in place.
+ */
+void MHD_http_unescape (char *val);
 
 /**
  * Header or cookie in HTTP request or response.
@@ -208,7 +213,7 @@
    * store it.  (MHD does not know or care what it
    * is).
    */
-  void * client_context;
+  void *client_context;
 
   /**
    * Request method.  Should be GET/POST/etc.  Allocated
@@ -350,11 +355,6 @@
   int headersSent;
 
   /**
-   * Are we processing the POST data?
-   */
-  int post_processed;
-
-  /**
    * HTTP response code.  Only valid if response object
    * is already set.
    */
@@ -391,7 +391,7 @@
 
   MHD_RequestCompletedCallback notify_completed;
 
-  void * notify_completed_cls;
+  void *notify_completed_cls;
 
   /**
    * PID of the select thread (if we have internal select)

Modified: libmicrohttpd/src/daemon/minimal_example.c
===================================================================
--- libmicrohttpd/src/daemon/minimal_example.c  2007-09-09 00:10:05 UTC (rev 
5616)
+++ libmicrohttpd/src/daemon/minimal_example.c  2007-09-09 03:56:10 UTC (rev 
5617)
@@ -41,8 +41,7 @@
           const char *url,
           const char *method,
           const char *upload_data,
-          const char *version, unsigned int *upload_data_size,
-         void ** unused)
+          const char *version, unsigned int *upload_data_size, void **unused)
 {
   const char *me = cls;
   struct MHD_Response *response;

Modified: libmicrohttpd/src/include/microhttpd.h
===================================================================
--- libmicrohttpd/src/include/microhttpd.h      2007-09-09 00:10:05 UTC (rev 
5616)
+++ libmicrohttpd/src/include/microhttpd.h      2007-09-09 03:56:10 UTC (rev 
5617)
@@ -84,7 +84,7 @@
 /**
  * Current version of the library.
  */
-#define MHD_VERSION 0x00000004
+#define MHD_VERSION 0x00000005
 
 /**
  * MHD-internal return codes.
@@ -428,6 +428,11 @@
 struct MHD_Response;
 
 /**
+ * Handle for POST processing.
+ */
+struct MHD_PostProcessor;
+
+/**
  * Allow or deny a client to connect.
  *
  *
@@ -555,6 +560,29 @@
 typedef void (*MHD_ContentReaderFreeCallback) (void *cls);
 
 /**
+ * Iterator over key-value pairs where the value
+ * maybe made available in increments and/or may
+ * not be zero-terminated.
+ *
+ * @param cls user-specified closure
+ * @param kind type of the value
+ * @param 0-terminated key for the value
+ * @param value pointer to size bytes of data at the
+ *              specified offset
+ * @param off offset of value in the overall data
+ * @param size number of bytes in value available 
+ * @return MHD_YES to continue iterating,
+ *         MHD_NO to abort the iteration
+ */
+typedef int
+  (*MHD_IncrementalKeyValueIterator) (void *cls,
+                                     enum MHD_ValueKind kind,
+                                     const char *key,
+                                     const char *value,
+                                     size_t off,
+                                     size_t size);
+
+/**
  * Start a webserver on the given port.
  * @param flags combination of MHD_FLAG values
  * @param port port to bind to
@@ -776,6 +804,57 @@
                                      const char *key);
 
 
+/**
+ * Create a PostProcessor.
+ * 
+ * A PostProcessor can be used to (incrementally)
+ * parse the data portion of a POST request.
+ *
+ * @param connection the connection on which the POST is
+ *        happening (used to determine the POST format)
+ * @param buffer_size maximum number of bytes to use for
+ *        internal buffering (used only for the parsing,
+ *        specifically the parsing of the keys).  A
+ *        tiny value (256-1024) should be sufficient.
+ *        Do NOT use 0.
+ * @param ikvi iterator to be called with the parsed data,
+ *        Must NOT be NULL.
+ * @param cls first argument to ikvi
+ * @return  NULL on error (out of memory, unsupported encoding),
+            otherwise a PP handle
+ */
+struct MHD_PostProcessor *
+MHD_create_post_processor(struct MHD_Connection * connection,
+                         unsigned int buffer_size,
+                         MHD_IncrementalKeyValueIterator ikvi,
+                         void * cls);
+
+/**
+ * Parse and process POST data.
+ * Call this function when POST data is available
+ * (usually during an MHD_AccessHandlerCallback)
+ * with the upload_data and upload_data_size.  
+ * Whenever possible, this will then cause calls
+ * to the MHD_IncrementalKeyValueIterator.  
+ *
+ * @param pp the post processor
+ * @param post_data post_data_len bytes of POST data
+ * @param post_data_len length of post_data
+ * @return MHD_YES on success, MHD_NO on error
+ *         (out-of-memory, iterator aborted, parse error)
+ */
+int
+MHD_post_process(struct MHD_PostProcessor * pp,
+                const char * post_data,
+                unsigned int post_data_len);
+
+/**
+ * Release PostProcessor resources.
+ */
+void 
+MHD_destroy_post_processor(struct MHD_PostProcessor * pp);
+
+
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
 #endif





reply via email to

[Prev in Thread] Current Thread [Next in Thread]