On Sat, 26 Nov 2016 15:30:28 +0300
Evgeny Grin <[email protected]> wrote:

> Looks like you are sending 4GiB-1 file on 32bit OS and sendfile failed
> as mmap operations are not supported on such file.
> Fallback to ordinal read()/send() should be fixed in
> b3f1a958ce613f304234ecb6506976db26c117dc.
> Could you retry with latest git version?
Sorry, I couldn't do that, because I'vn't found a way to reproduce
it in the same environment, but I found some part of the problem.

nodogsplash is giving a fd of a directory to libmicrohttpd and lseek()
was used to define the size of the file without checking the return
value resulting in the size = 4GiB-1.

But anyway, mmap on a directory doesn't look like a good idea.

On my working machine a simple test is not going into a indef loop.
Passing a directory resulting in a direct close of the connection (no
headers, no data).

Best
lynxis
-- 
Alexander Couzens

mail: [email protected]
jabber: [email protected]
mobile: +4915123277221
gpg: 390D CF78 8BF9 AA50 4F8F  F1E2 C29E 9DA6 A0DF 8604
From 6c32da8be007180534c5891135203aa5793efb31 Mon Sep 17 00:00:00 2001
From: Alexander Couzens <[email protected]>
Date: Thu, 19 Jan 2017 16:51:18 +0100
Subject: [PATCH][NOT-FOR-MERGE] try to pass a directory

---
 src/testcurl/test_get.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/src/testcurl/test_get.c b/src/testcurl/test_get.c
index 951db10e..6df53286 100644
--- a/src/testcurl/test_get.c
+++ b/src/testcurl/test_get.c
@@ -611,6 +611,94 @@ testEmptyGet (int poll_flag)
   return 0;
 }
 
+static int
+ahc_directory (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)
+{
+  static int ptr;
+  struct MHD_Response *response;
+  int ret;
+  int fd;
+  size_t size;
+
+
+  if (0 != strcasecmp ("GET", method))
+    return MHD_NO;              /* unexpected method */
+  if ((fd = open("/tmp", O_RDONLY)) < 0)
+    return MHD_NO;              /* unexpected method */
+  size = lseek(fd, 0, SEEK_END);
+
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  response = MHD_create_response_from_fd (size, fd);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret != MHD_NO)
+    abort ();
+  return ret;
+}
+
+static int
+testDirectoryFd (int poll_flag)
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  int excess_found = 0;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG  | poll_flag,
+                        11081, NULL, NULL, &ahc_directory, NULL, MHD_OPTION_END);
+  if (d == NULL)
+    return 67108864;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/directoryfd";);
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  curl_easy_setopt (c, CURLOPT_DEBUGFUNCTION, &curlExcessFound);
+  curl_easy_setopt (c, CURLOPT_DEBUGDATA, &excess_found);
+  curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 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);
+  /* NOTE: use of CONNECTTIMEOUT without also
+     setting NOSIGNAL results in really weird
+     crashes on my system!*/
+  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+  if (CURLE_OK != (errornum = curl_easy_perform (c)))
+    {
+      fprintf (stderr,
+               "curl_easy_perform failed: `%s'\n",
+               curl_easy_strerror (errornum));
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      return 134217728;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != 0)
+    return 268435456;
+  if (excess_found)
+    return 536870912;
+  return 0;
+}
 
 int
 main (int argc, char *const *argv)
@@ -628,6 +716,7 @@ main (int argc, char *const *argv)
   errorCount += testStopRace (0);
   errorCount += testExternalGet ();
   errorCount += testEmptyGet (0);
+  errorCount += testDirectoryFd (0);
   if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
     {
       errorCount += testInternalGet(MHD_USE_POLL);
-- 
2.11.0

Attachment: pgphC4wPsgCQg.pgp
Description: OpenPGP digital signature

Reply via email to