gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r10530 - in libmicrohttpd: . src/daemon src/testcurl


From: gnunet
Subject: [GNUnet-SVN] r10530 - in libmicrohttpd: . src/daemon src/testcurl
Date: Wed, 10 Mar 2010 13:19:27 +0100

Author: grothoff
Date: 2010-03-10 13:19:27 +0100 (Wed, 10 Mar 2010)
New Revision: 10530

Modified:
   libmicrohttpd/ChangeLog
   libmicrohttpd/src/daemon/connection.c
   libmicrohttpd/src/testcurl/daemontest_post.c
Log:
bugfix

Modified: libmicrohttpd/ChangeLog
===================================================================
--- libmicrohttpd/ChangeLog     2010-03-10 10:55:01 UTC (rev 10529)
+++ libmicrohttpd/ChangeLog     2010-03-10 12:19:27 UTC (rev 10530)
@@ -1,3 +1,7 @@
+Wed Mar 10 13:18:26 CET 2010
+       Fixing bug in 100 CONTINUE replacement when handling POSTs
+       (see report on mailinglist), with testcase. -CG/MC
+
 Tue Feb 23 09:16:15 CET 2010
        Added configure check for endianness to define WORDS_BIGENDIAN
        which fixes SSL support on big endian architectures. -JA/CG
@@ -15,7 +19,7 @@
 Thu Jan 28 20:35:48 CET 2010
        Make sure addresses returned by memory pool are
        aligned (fixes bus errors on Sparc). -CG
-       
+
 Thu Dec 17 20:26:52 CET 2009
        poll.h is not stricly required anymore. -ND
 

Modified: libmicrohttpd/src/daemon/connection.c
===================================================================
--- libmicrohttpd/src/daemon/connection.c       2010-03-10 10:55:01 UTC (rev 
10529)
+++ libmicrohttpd/src/daemon/connection.c       2010-03-10 12:19:27 UTC (rev 
10530)
@@ -1140,6 +1140,7 @@
   return MHD_YES;
 }
 
+
 /**
  * Call the handler of the application for this
  * connection.  Handles chunking of the upload
@@ -1149,6 +1150,41 @@
 call_connection_handler (struct MHD_Connection *connection)
 {
   size_t processed;
+
+  if (connection->response != NULL)
+    return;                     /* already queued a response */  
+  processed = 0;
+  connection->client_aware = MHD_YES;
+  if (MHD_NO ==
+      connection->daemon->default_handler (connection->daemon->
+                                          default_handler_cls,
+                                          connection, connection->url,
+                                          connection->method,
+                                          connection->version,
+                                          NULL, &processed,
+                                          &connection->client_context))
+    {
+      /* serious internal error, close connection */
+#if HAVE_MESSAGES
+      MHD_DLOG (connection->daemon,
+               "Internal application error, closing connection.\n");
+#endif
+      connection_close_error (connection);
+      return;
+    }
+}
+
+
+
+/**
+ * Call the handler of the application for this
+ * connection.  Handles chunking of the upload
+ * as well as normal uploads.
+ */
+static void
+process_request_body (struct MHD_Connection *connection)
+{
+  size_t processed;
   size_t available;
   size_t used;
   size_t i;
@@ -1949,7 +1985,7 @@
         case MHD_CONNECTION_CONTINUE_SENT:
           if (connection->read_buffer_offset != 0)
             {
-              call_connection_handler (connection);     /* loop call */
+              process_request_body (connection);     /* loop call */
               if (connection->state == MHD_CONNECTION_CLOSED)
                 continue;
             }

Modified: libmicrohttpd/src/testcurl/daemontest_post.c
===================================================================
--- libmicrohttpd/src/testcurl/daemontest_post.c        2010-03-10 10:55:01 UTC 
(rev 10529)
+++ libmicrohttpd/src/testcurl/daemontest_post.c        2010-03-10 12:19:27 UTC 
(rev 10530)
@@ -409,8 +409,182 @@
   return 0;
 }
 
+static int
+ahc_cancel (void *cls,
+           struct MHD_Connection *connection,
+           const char *url,
+           const char *method,
+           const char *version,
+           const char *upload_data, size_t *upload_data_size,
+           void **unused)
+{
+  struct MHD_Response *response;
+  int ret;
 
+  if (0 != strcmp ("POST", method))
+    {
+      fprintf (stderr,
+              "Unexpected method `%s'\n", method);
+      return MHD_NO; 
+    }
 
+  if (*unused == NULL)
+    {
+      *unused = "wibble";
+      /* We don't want the body. Send a 500. */
+      response = MHD_create_response_from_data(0, NULL, 0, 0);
+      ret = MHD_queue_response(connection, 500, response);
+      if (ret != MHD_YES)
+       fprintf(stderr, "Failed to queue response\n");
+      MHD_destroy_response(response);
+      return ret;
+    }
+  else
+    {
+      fprintf(stderr, 
+             "In ahc_cancel again. This should not happen.\n");
+      return MHD_NO;
+    }
+}
+
+struct CRBC
+{
+  const char *buffer;
+  size_t size;
+  size_t pos;
+};
+
+static size_t 
+readBuffer(void *p, size_t size, size_t nmemb, void *opaque)
+{
+  struct CRBC *data = opaque;
+  size_t required = size * nmemb;
+  size_t left = data->size - data->pos;
+  
+  if (required > left)
+    required = left;
+  
+  memcpy(p, data->buffer + data->pos, required);
+  data->pos += required;
+  
+  return required/size;
+}
+
+static size_t 
+slowReadBuffer(void *p, size_t size, size_t nmemb, void *opaque)
+{
+  sleep(1);
+  return readBuffer(p, size, nmemb, opaque);
+}
+
+#define FLAG_EXPECT_CONTINUE 1
+#define FLAG_CHUNKED 2
+#define FLAG_FORM_DATA 4
+#define FLAG_SLOW_READ 8
+#define FLAG_COUNT 16
+
+static int
+testMultithreadedPostCancelPart(int flags)
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+  struct curl_slist *headers = NULL;
+  long response_code;
+  CURLcode cc;
+  int result = 0;
+  struct CRBC crbc;
+
+  /* Don't test features that aren't available with HTTP/1.0 in
+   * HTTP/1.0 mode. */
+  if (!oneone && (flags & (FLAG_EXPECT_CONTINUE | FLAG_CHUNKED)))
+    return 0;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
+                        1081, NULL, NULL, &ahc_cancel, NULL, MHD_OPTION_END);
+  if (d == NULL)
+    return 32768;
+
+  crbc.buffer = "Test content";
+  crbc.size = strlen(crbc.buffer);
+  crbc.pos = 0;
+  
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://localhost:1081/hello_world";);
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  curl_easy_setopt (c, CURLOPT_READFUNCTION, (flags & FLAG_SLOW_READ) ? 
&slowReadBuffer : &readBuffer);
+  curl_easy_setopt (c, CURLOPT_READDATA, &crbc);
+  curl_easy_setopt (c, CURLOPT_POSTFIELDS, NULL);
+  curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, crbc.size);
+  curl_easy_setopt (c, CURLOPT_POST, 1L);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+  if (oneone)
+    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+  else
+    curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+  // NOTE: use of CONNECTTIMEOUT without also
+  //   setting NOSIGNAL results in really weird
+  //   crashes on my system!
+  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+
+  if (flags & FLAG_CHUNKED)
+      headers = curl_slist_append(headers, "Transfer-Encoding: chunked");
+  if (!(flags & FLAG_FORM_DATA))
+  headers = curl_slist_append(headers, "Content-Type: 
application/octet-stream");
+  if (flags & FLAG_EXPECT_CONTINUE)
+      headers = curl_slist_append(headers, "Expect: 100-Continue");
+  curl_easy_setopt(c, CURLOPT_HTTPHEADER, headers);
+  
+  if (CURLE_HTTP_RETURNED_ERROR != (errornum = curl_easy_perform (c)))
+    {
+      fprintf (stderr,
+               "flibbet curl_easy_perform didn't fail as expected: `%s' %d\n",
+               curl_easy_strerror (errornum), errornum);
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      curl_slist_free_all(headers);
+      return 65536;
+    }
+  
+  if (CURLE_OK != (cc = curl_easy_getinfo(c, CURLINFO_RESPONSE_CODE, 
&response_code)))
+    {
+      fprintf(stderr, "curl_easy_getinfo failed: '%s'\n", 
curl_easy_strerror(errornum));
+      result = 65536;
+    }
+  
+  if (!result && (response_code != 500))
+    {
+      fprintf(stderr, "Unexpected response code: %ld\n", response_code);
+      result = 131072;
+    }
+  
+  if (!result && (cbc.pos != 0))
+    result = 262144;
+
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  curl_slist_free_all(headers);
+  return result;
+}
+
+static int
+testMultithreadedPostCancel()
+{
+  int result = 0;
+  int flags;
+  for(flags = 0; flags < FLAG_COUNT; ++flags)
+    result |= testMultithreadedPostCancelPart(flags);  
+  return result;
+}
+
 int
 main (int argc, char *const *argv)
 {
@@ -419,6 +593,7 @@
   oneone = NULL != strstr (argv[0], "11");
   if (0 != curl_global_init (CURL_GLOBAL_WIN32))
     return 2;
+  errorCount += testMultithreadedPostCancel ();
   errorCount += testInternalPost ();
   errorCount += testMultithreadedPost ();
   errorCount += testMultithreadedPoolPost ();





reply via email to

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