Example #1
0
/**
 * Run the MHD external event loop using select.
 *
 * @param daemon daemon to run it for
 */
static void
run_mhd_epoll_loop (struct MHD_Daemon *daemon)
{
  const union MHD_DaemonInfo *di;
  MHD_socket ep;
  fd_set rs;
  MHD_UNSIGNED_LONG_LONG to;
  struct timeval tv;

  di = MHD_get_daemon_info (daemon,
                            MHD_DAEMON_INFO_EPOLL_FD);
  ep = di->listen_fd;
  while (! done)
    {
      FD_ZERO (&rs);
      to = 1000;

      FD_SET (ep, &rs);
      (void) MHD_get_timeout (daemon,
                              &to);
      if (1000 < to)
        to = 1000;
      tv.tv_sec = to / 1000;
      tv.tv_usec = 1000 * (to % 1000);
      select (ep + 1,
              &rs,
              NULL,
              NULL,
              &tv);
      MHD_run (daemon);
    }
}
Example #2
0
/* perform a HTTP GET request via SSL/TLS */
static int
test_secure_get (FILE * test_fd,
		 const char *cipher_suite,
		 int proto_version)
{
  int ret;
  struct MHD_Daemon *d;
  int port;

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    port = 3041;

  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS |
                        MHD_USE_ERROR_LOG, port,
                        NULL, NULL, &http_ahc, NULL,
                        MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
                        MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
                        MHD_OPTION_END);

  if (d == NULL)
    {
      fprintf (stderr, MHD_E_SERVER_INIT);
      return -1;
    }
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return -1; }
      port = (int)dinfo->port;
    }

  ret = test_https_transfer (test_fd, port, cipher_suite, proto_version);

  MHD_stop_daemon (d);
  return ret;
}
Example #3
0
static int
testMultithreadedPoolGet ()
{
  struct MHD_Daemon *d;
  char buf[2048];
  int k;
  int port;
  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    {
      port = 1261;
      if (oneone)
        port += 5;
    }

  /* Test only valid for HTTP/1.1 (uses persistent connections) */
  if (!oneone)
    return 0;

  d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
                        port, NULL, NULL, &ahc_echo, "GET",
                        MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2,
                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT,
                        MHD_OPTION_END);
  if (d == NULL)
    return 16;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }

  for (k = 0; k < 3; ++k)
    {
      struct CBC cbc[3];
      CURL *cenv[3];
      int i;

      for (i = 0; i < 3; ++i)
        {
          CURL *c;
          CURLcode errornum;

          cenv[i] = c = curl_easy_init ();
          cbc[i].buf = buf;
          cbc[i].size = 2048;
          cbc[i].pos = 0;

          curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
          curl_easy_setopt (c, CURLOPT_PORT, (long)port);
          curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
          curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc[i]);
          curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
          curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
          curl_easy_setopt (c, CURLOPT_FORBID_REUSE, 0L);
          curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
          curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
          /* NOTE: use of CONNECTTIMEOUT without also
           *   setting NOSIGNAL results in really weird
           *   crashes on my system! */
          curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);

          errornum = curl_easy_perform (c);
          if ( ( (CURLE_OK != errornum) && (i <  2) ) ||
	       ( (CURLE_OK == errornum) && (i == 2) ) )
            {
              int j;

              /* First 2 should succeed */
              if (i < 2)
                fprintf (stderr,
                         "curl_easy_perform failed: `%s'\n",
                         curl_easy_strerror (errornum));

              /* Last request should have failed */
              else
                fprintf (stderr,
                         "No error on IP address over limit\n");

              for (j = 0; j < i; ++j)
                curl_easy_cleanup (cenv[j]);
              MHD_stop_daemon (d);
              return 32;
            }
        }

      /* Cleanup the environments */
      for (i = 0; i < 3; ++i)
        curl_easy_cleanup (cenv[i]);

      (void)sleep(2);

      for (i = 0; i < 2; ++i)
        {
          if (cbc[i].pos != strlen ("/hello_world"))
            {
              MHD_stop_daemon (d);
              return 64;
            }
          if (0 != strncmp ("/hello_world", cbc[i].buf, strlen ("/hello_world")))
            {
              MHD_stop_daemon (d);
              return 128;
            }
        }


    }
  MHD_stop_daemon (d);
  return 0;
}
Example #4
0
static int
testMultithreadedGet ()
{
  struct MHD_Daemon *d;
  char buf[2048];
  int k;
  unsigned int success;
  unsigned int failure;
  int port;

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    {
      port = 1260;
      if (oneone)
        port += 5;
    }

  /* Test only valid for HTTP/1.1 (uses persistent connections) */
  if (!oneone)
    return 0;

  d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
                        port, NULL, NULL,
                        &ahc_echo, "GET",
                        MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2,
                        MHD_OPTION_END);
  if (d == NULL)
    return 16;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }

  for (k = 0; k < 3; ++k)
    {
      struct CBC cbc[3];
      CURL *cenv[3];
      int i;

      success = 0;
      failure = 0;
      for (i = 0; i < 3; ++i)
        {
          CURL *c;
          CURLcode errornum;

          cenv[i] = c = curl_easy_init ();
          cbc[i].buf = buf;
          cbc[i].size = 2048;
          cbc[i].pos = 0;

          curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
          curl_easy_setopt (c, CURLOPT_PORT, (long)port);
          curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
          curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc[i]);
          curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
          curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
          curl_easy_setopt (c, CURLOPT_FORBID_REUSE, 0L);
          curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
          curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
          /* NOTE: use of CONNECTTIMEOUT without also
           *   setting NOSIGNAL results in really weird
           *   crashes on my system! */
          curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);

          errornum = curl_easy_perform (c);
          if (CURLE_OK == errornum)
            success++;
          else
            failure++;
        }

      /* Cleanup the environments */
      for (i = 0; i < 3; ++i)
        curl_easy_cleanup (cenv[i]);
      if ( (2 != success) ||
           (1 != failure) )
      {
        fprintf (stderr,
                 "Unexpected number of success (%u) or failure (%u)\n",
                 success,
                 failure);
        MHD_stop_daemon (d);
        return 32;
      }

      (void)sleep(2);

      for (i = 0; i < 2; ++i)
        {
          if (cbc[i].pos != strlen ("/hello_world"))
            {
              MHD_stop_daemon (d);
              return 64;
            }
          if (0 != strncmp ("/hello_world", cbc[i].buf, strlen ("/hello_world")))
            {
              MHD_stop_daemon (d);
              return 128;
            }
        }
    }
  MHD_stop_daemon (d);
  return 0;
}
int
main (int argc, char *const *argv)
{
  int errorCount = 0;;
  struct MHD_Daemon *d;
  gnutls_session_t session;
  gnutls_datum_t key;
  gnutls_datum_t cert;
  gnutls_certificate_credentials_t xcred;
  int port;
  (void)argc;   /* Unused. Silent compiler warning. */

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    port = 3070;

#ifdef MHD_HTTPS_REQUIRE_GRYPT
  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
#endif /* MHD_HTTPS_REQUIRE_GRYPT */
  gnutls_global_init ();
  gnutls_global_set_log_level (11);

  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS |
                        MHD_USE_ERROR_LOG, port,
                        NULL, NULL, &http_dummy_ahc, NULL,
                        MHD_OPTION_CONNECTION_TIMEOUT, TIME_OUT,
                        MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
                        MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
                        MHD_OPTION_END);

  if (NULL == d)
    {
      fprintf (stderr, MHD_E_SERVER_INIT);
      return -1;
    }
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return -1; }
      port = (int)dinfo->port;
    }

  if (0 != setup_session (&session, &key, &cert, &xcred))
    {
      fprintf (stderr, "failed to setup session\n");
      return 1;
    }
  errorCount += test_tls_session_time_out (session, port);
  teardown_session (session, &key, &cert, xcred);

  print_test_result (errorCount, argv[0]);

  MHD_stop_daemon (d);
  gnutls_global_deinit ();

  return errorCount != 0 ? 1 : 0;
}
static int
testExternalGet ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket maxsock;
#ifdef MHD_WINSOCK_SOCKETS
  int maxposixs; /* Max socket number unused on W32 */
#else  /* MHD_POSIX_SOCKETS */
#define maxposixs maxsock
#endif /* MHD_POSIX_SOCKETS */
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  int port;

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    {
      port = 1410;
      if (oneone)
        port += 5;
    }

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
                        port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
  if (d == NULL)
    return 256;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL,
                    "http://127.0.0.1/hello+world?k=v+x&hash=%23foo&space=%A0bar");
  curl_easy_setopt (c, CURLOPT_PORT, (long)port);
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
  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_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
  /* NOTE: use of CONNECTTIMEOUT without also
     setting NOSIGNAL results in really weird
     crashes on my system! */
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);


  multi = curl_multi_init ();
  if (multi == NULL)
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 512;
    }
  mret = curl_multi_add_handle (multi, c);
  if (mret != CURLM_OK)
    {
      curl_multi_cleanup (multi);
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      return 1024;
    }
  start = time (NULL);
  while ((time (NULL) - start < 5) && (multi != NULL))
    {
      maxsock = MHD_INVALID_SOCKET;
      maxposixs = -1;
      FD_ZERO (&rs);
      FD_ZERO (&ws);
      FD_ZERO (&es);
      curl_multi_perform (multi, &running);
      mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
      if (mret != CURLM_OK)
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 2048;
        }
      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
        {
          curl_multi_remove_handle (multi, c);
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 4096;
        }
      tv.tv_sec = 0;
      tv.tv_usec = 1000;
      if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
        {
#ifdef MHD_POSIX_SOCKETS
          if (EINTR != errno)
            abort ();
#else
          if (WSAEINVAL != WSAGetLastError() || 0 != rs.fd_count || 0 != ws.fd_count || 0 != es.fd_count)
            abort ();
          Sleep (1000);
#endif
        }
      curl_multi_perform (multi, &running);
      if (running == 0)
        {
          msg = curl_multi_info_read (multi, &running);
          if (msg == NULL)
            break;
          if (msg->msg == CURLMSG_DONE)
            {
              if (msg->data.result != CURLE_OK)
                printf ("%s failed at %s:%d: `%s'\n",
                        "curl_multi_perform",
                        __FILE__,
                        __LINE__, curl_easy_strerror (msg->data.result));
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              c = NULL;
              multi = NULL;
            }
        }
      MHD_run (d);
    }
  if (multi != NULL)
    {
      curl_multi_remove_handle (multi, c);
      curl_easy_cleanup (c);
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello+world"))
    return 8192;
  if (0 != strncmp ("/hello+world", cbc.buf, strlen ("/hello+world")))
    return 16384;
  return 0;
}
Example #7
0
static int
testUnknownPortGet (int poll_flag)
{
  struct MHD_Daemon *d;
  const union MHD_DaemonInfo *di;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLcode errornum;

  struct sockaddr_in addr;
  socklen_t addr_len = sizeof(addr);
  memset(&addr, 0, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_port = 0;
  addr.sin_addr.s_addr = INADDR_ANY;

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG  | poll_flag,
                        1, NULL, NULL, &ahc_echo, "GET",
                        MHD_OPTION_SOCK_ADDR, &addr,
                        MHD_OPTION_END);
  if (d == NULL)
    return 32768;

  di = MHD_get_daemon_info (d, MHD_DAEMON_INFO_LISTEN_FD);
  if (di == NULL)
    return 65536;

  if (0 != getsockname(di->listen_fd, &addr, &addr_len))
    return 131072;

  if (addr.sin_family != AF_INET)
    return 26214;

  snprintf(buf, sizeof(buf), "http://localhost:%hu/hello_world",
           ntohs(addr.sin_port));

  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, buf);
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
  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 524288;
    }
  curl_easy_cleanup (c);
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    return 1048576;
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 2097152;
  return 0;
}
Example #8
0
static int
testExternalPost ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket maxsock;
#ifdef MHD_WINSOCK_SOCKETS
  int maxposixs; /* Max socket number unused on W32 */
#else  /* MHD_POSIX_SOCKETS */
#define maxposixs maxsock
#endif /* MHD_POSIX_SOCKETS */
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  int i;
  unsigned long long timeout;
  long ctimeout;
  char url[1024];
  int port;

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    {
      port = 1353;
      if (oneone)
        port += 10;
    }

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
                        port, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
  if (d == NULL)
    return 256;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }
  multi = curl_multi_init ();
  if (multi == NULL)
    {
      MHD_stop_daemon (d);
      return 512;
    }
  for (i = 0; i < LOOPCOUNT; i++)
    {
      if (99 == i % 100)
	fprintf (stderr, ".");
      c = curl_easy_init ();
      cbc.pos = 0;
      buf[0] = '\0';
      snprintf (url,
                sizeof (url),
                "http://127.0.0.1:%d/hw%d",
                port,
                i);
      curl_easy_setopt (c, CURLOPT_URL, url);
      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
      curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
      curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
      curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
      curl_easy_setopt (c, CURLOPT_POST, 1L);
      curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
      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, 150L);
      /* NOTE: use of CONNECTTIMEOUT without also
       *   setting NOSIGNAL results in really weird
       *   crashes on my system! */
      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
      mret = curl_multi_add_handle (multi, c);
      if (mret != CURLM_OK)
        {
          curl_multi_cleanup (multi);
          curl_easy_cleanup (c);
          MHD_stop_daemon (d);
          return 1024;
        }
      start = time (NULL);
      while ((time (NULL) - start < 5) && (multi != NULL))
        {
          maxsock = MHD_INVALID_SOCKET;
          maxposixs = -1;
          FD_ZERO (&rs);
          FD_ZERO (&ws);
          FD_ZERO (&es);
          while (CURLM_CALL_MULTI_PERFORM ==
                 curl_multi_perform (multi, &running));
          mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
          if (mret != CURLM_OK)
            {
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              MHD_stop_daemon (d);
              return 2048;
            }
          if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
            {
              curl_multi_remove_handle (multi, c);
              curl_multi_cleanup (multi);
              curl_easy_cleanup (c);
              MHD_stop_daemon (d);
              return 4096;
            }
          if (MHD_NO == MHD_get_timeout (d, &timeout))
            timeout = 100;      /* 100ms == INFTY -- CURL bug... */
          if ((CURLM_OK == curl_multi_timeout (multi, &ctimeout)) &&
              (ctimeout < (long long)timeout) && (ctimeout >= 0))
            timeout = ctimeout;
	  if ( (c == NULL) || (running == 0) )
	    timeout = 0; /* terminate quickly... */
          tv.tv_sec = timeout / 1000;
          tv.tv_usec = (timeout % 1000) * 1000;
          if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
	    {
	      if (EINTR == errno)
		continue;
	      fprintf (stderr,
		       "select failed: %s\n",
		       strerror (errno));
	      break;
	    }
          while (CURLM_CALL_MULTI_PERFORM ==
                 curl_multi_perform (multi, &running));
          if (running == 0)
            {
              msg = curl_multi_info_read (multi, &running);
              if (msg == NULL)
                break;
              if (msg->msg == CURLMSG_DONE)
                {
                  if (msg->data.result != CURLE_OK)
                    printf ("%s failed at %s:%d: `%s'\n",
                            "curl_multi_perform",
                            __FILE__,
                            __LINE__, curl_easy_strerror (msg->data.result));
                  curl_multi_remove_handle (multi, c);
                  curl_easy_cleanup (c);
                  c = NULL;
                }
            }
          MHD_run (d);
        }
      if (c != NULL)
        {
          curl_multi_remove_handle (multi, c);
          curl_easy_cleanup (c);
        }
      if ((buf[0] != 'O') || (buf[1] != 'K'))
        {
          curl_multi_cleanup (multi);
          MHD_stop_daemon (d);
          return 8192;
        }
    }
  curl_multi_cleanup (multi);
  MHD_stop_daemon (d);
  if (LOOPCOUNT >= 99)
    fprintf (stderr, "\n");
  return 0;
}
Example #9
0
static int
testMultithreadedPoolPost ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLcode errornum;
  int i;
  char url[1024];
  int port;

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    {
      port = 1352;
      if (oneone)
        port += 10;
    }

  cbc.buf = buf;
  cbc.size = 2048;
  d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
                        port, NULL, NULL, &ahc_echo, NULL,
                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
  if (d == NULL)
    return 16;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }
  for (i = 0; i < LOOPCOUNT; i++)
    {
      if (99 == i % 100)
        fprintf (stderr, ".");
      c = curl_easy_init ();
      cbc.pos = 0;
      buf[0] = '\0';
      snprintf (url,
                sizeof (url),
                "http://127.0.0.1:%d/hw%d",
                port,
                i);
      curl_easy_setopt (c, CURLOPT_URL, url);
      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
      curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
      curl_easy_setopt (c, CURLOPT_POSTFIELDS, POST_DATA);
      curl_easy_setopt (c, CURLOPT_POSTFIELDSIZE, strlen (POST_DATA));
      curl_easy_setopt (c, CURLOPT_POST, 1L);
      curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
      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, 150L);
      /* NOTE: use of CONNECTTIMEOUT without also
       *   setting NOSIGNAL results in really weird
       *   crashes on my system! */
      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
      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 32;
        }
      curl_easy_cleanup (c);
      if ((buf[0] != 'O') || (buf[1] != 'K'))
        {
          MHD_stop_daemon (d);
          return 64;
        }
    }
  MHD_stop_daemon (d);
  if (LOOPCOUNT >= 99)
    fprintf (stderr, "\n");
  return 0;
}
static int
testDigestAuth ()
{
  CURL *c;
  CURLcode errornum;
  struct MHD_Daemon *d;
  struct CBC cbc;
  char buf[2048];
  char rnd[8];
  int port;
  char url[128];
#ifndef WINDOWS
  int fd;
  size_t len;
  size_t off = 0;
#endif /* ! WINDOWS */

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    port = 1160;

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
#ifndef WINDOWS
  fd = open("/dev/urandom", O_RDONLY);
  if (-1 == fd)
    {
      fprintf(stderr, "Failed to open `%s': %s\n",
              "/dev/urandom",
              strerror(errno));
      return 1;
    }
  while (off < 8)
    {
      len = read(fd, rnd, 8);
      if (len == (size_t)-1)
        {
          fprintf(stderr,
                  "Failed to read `%s': %s\n",
                  "/dev/urandom",
                  strerror(errno));
          (void) close(fd);
          return 1;
        }
      off += len;
    }
  (void) close(fd);
#else
  {
    HCRYPTPROV cc;
    BOOL b;
    b = CryptAcquireContext (&cc, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
    if (b == 0)
    {
      fprintf (stderr, "Failed to acquire crypto provider context: %lu\n",
          GetLastError ());
      return 1;
    }
    b = CryptGenRandom (cc, 8, (BYTE*)rnd);
    if (b == 0)
    {
      fprintf (stderr, "Failed to generate 8 random bytes: %lu\n",
          GetLastError ());
    }
    CryptReleaseContext (cc, 0);
    if (b == 0)
      return 1;
  }
#endif
  d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
                        port, NULL, NULL, &ahc_echo, PAGE,
			MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof (rnd), rnd,
			MHD_OPTION_NONCE_NC_SIZE, 300,
			MHD_OPTION_END);
  if (d == NULL)
    return 1;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }
  snprintf (url,
            sizeof (url),
            "http://127.0.0.1:%d/bar%%20foo%%3Fkey%%3Dvalue",
            port);
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, url);
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
  curl_easy_setopt (c, CURLOPT_USERPWD, "testuser:testpass");
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  /* NOTE: use of CONNECTTIMEOUT without also
     setting NOSIGNAL results in really weird
     crashes on my system!*/
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
  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 2;
    }
  curl_easy_cleanup (c);
  MHD_stop_daemon (d);
  if (cbc.pos != strlen (PAGE))
    return 4;
  if (0 != strncmp (PAGE, cbc.buf, strlen (PAGE)))
    return 8;
  return 0;
}
Example #11
0
static int
testMultithreadedPoolPut ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  unsigned int pos = 0;
  int done_flag = 0;
  CURLcode errornum;
  int port;

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    {
      port = 1452;
      if (oneone)
        port += 10;
    }

  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG,
                        port,
                        NULL, NULL, &ahc_echo, &done_flag,
                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
  if (d == NULL)
    return 16;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }
  c = curl_easy_init ();
  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world");
  curl_easy_setopt (c, CURLOPT_PORT, (long)port);
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer);
  curl_easy_setopt (c, CURLOPT_READDATA, &pos);
  curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
  curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
  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, 150L);
  /* NOTE: use of CONNECTTIMEOUT without also
   *   setting NOSIGNAL results in really weird
   *   crashes on my system! */
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
  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 32;
    }
  curl_easy_cleanup (c);
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    return 64;
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 128;

  return 0;
}
Example #12
0
static int
testExternalGet (int port)
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLM *multi;
  CURLMcode mret;
  fd_set rs;
  fd_set ws;
  fd_set es;
  MHD_socket maxsock;
#ifdef MHD_WINSOCK_SOCKETS
  int maxposixs; /* Max socket number unused on W32 */
#else  /* MHD_POSIX_SOCKETS */
#define maxposixs maxsock
#endif /* MHD_POSIX_SOCKETS */
  int running;
  struct CURLMsg *msg;
  time_t start;
  struct timeval tv;
  unsigned int i;
  char url[64];

  if (MHD_NO != MHD_is_feature_supported(MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;

  multi = NULL;
  cbc.buf = buf;
  cbc.size = 2048;
  d = MHD_start_daemon (MHD_USE_ERROR_LOG,
                        port, NULL, NULL,
                        &ahc_echo, "GET",
                        MHD_OPTION_END);
  if (NULL == d)
    return 256;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }
  snprintf (url,
            sizeof (url),
            "http://127.0.0.1:%d/hello_world",
            port);
  start_timer ();
  multi = curl_multi_init ();
  if (multi == NULL)
    {
      MHD_stop_daemon (d);
      return 512;
    }
  for (i=0;i<ROUNDS;i++)
    {
      cbc.pos = 0;
      c = curl_easy_init ();
      curl_easy_setopt (c, CURLOPT_URL, url);
      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
      curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
      curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
      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_TIMEOUT, 150L);
      curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
      /* NOTE: use of CONNECTTIMEOUT without also
	 setting NOSIGNAL results in really weird
	 crashes on my system! */
      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
      mret = curl_multi_add_handle (multi, c);
      if (mret != CURLM_OK)
	{
	  curl_multi_cleanup (multi);
	  curl_easy_cleanup (c);
	  MHD_stop_daemon (d);
	  return 1024;
	}
      start = time (NULL);
      while ((time (NULL) - start < 5) && (c != NULL))
	{
	  maxsock = MHD_INVALID_SOCKET;
	  maxposixs = -1;
	  FD_ZERO (&rs);
	  FD_ZERO (&ws);
	  FD_ZERO (&es);
	  curl_multi_perform (multi, &running);
	  mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs);
	  if (mret != CURLM_OK)
	    {
	      curl_multi_remove_handle (multi, c);
	      curl_multi_cleanup (multi);
	      curl_easy_cleanup (c);
	      MHD_stop_daemon (d);
	      return 2048;
	    }
	  if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock))
	    {
	      curl_multi_remove_handle (multi, c);
	      curl_multi_cleanup (multi);
	      curl_easy_cleanup (c);
	      MHD_stop_daemon (d);
	      return 4096;
	    }
	  tv.tv_sec = 0;
	  tv.tv_usec = 1000;
	  if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv))
            {
#ifdef MHD_POSIX_SOCKETS
              if (EINTR != errno)
                abort ();
#else
              if (WSAEINVAL != WSAGetLastError() || 0 != rs.fd_count || 0 != ws.fd_count || 0 != es.fd_count)
                abort ();
              Sleep (1000);
#endif
            }
	  curl_multi_perform (multi, &running);
	  if (running == 0)
	    {
	      msg = curl_multi_info_read (multi, &running);
	      if (msg == NULL)
		break;
	      if (msg->msg == CURLMSG_DONE)
		{
		  if (msg->data.result != CURLE_OK)
		    printf ("%s failed at %s:%d: `%s'\n",
			    "curl_multi_perform",
			    __FILE__,
			    __LINE__, curl_easy_strerror (msg->data.result));
		  curl_multi_remove_handle (multi, c);
		  curl_easy_cleanup (c);
		  c = NULL;
		}
	    }
	  /* two possibilities here; as select sets are
	     tiny, this makes virtually no difference
	     in actual runtime right now, even though the
	     number of select calls is virtually cut in half
	     (and 'select' is the most expensive of our system
	     calls according to 'strace') */
	  if (0)
	    MHD_run (d);
	  else
	    MHD_run_from_select (d, &rs, &ws, &es);
	}
      if (NULL != c)
	{
	  curl_multi_remove_handle (multi, c);
	  curl_easy_cleanup (c);
	  fprintf (stderr, "Timeout!?\n");
	}
    }
  stop ("external select");
  if (multi != NULL)
    {
      curl_multi_cleanup (multi);
    }
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    return 8192;
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 16384;
  return 0;
}
Example #13
0
static int
testMultithreadedPoolGet (int port, int poll_flag)
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  CURLcode errornum;
  unsigned int i;
  char url[64];

  if (MHD_NO != MHD_is_feature_supported(MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;

  cbc.buf = buf;
  cbc.size = 2048;
  d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | poll_flag,
                        port, NULL, NULL, &ahc_echo, "GET",
                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
  if (d == NULL)
    return 16;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }
  snprintf (url,
            sizeof (url),
            "http://127.0.0.1:%d/hello_world",
            port);
  start_timer ();
  for (i=0;i<ROUNDS;i++)
    {
      cbc.pos = 0;
      c = curl_easy_init ();
      curl_easy_setopt (c, CURLOPT_URL, url);
      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
      curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
      curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
      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, 150L);
      /* NOTE: use of CONNECTTIMEOUT without also
	 setting NOSIGNAL results in really weird
	 crashes on my system!*/
      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
      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 32;
	}
      curl_easy_cleanup (c);
    }
  stop (0 != (poll_flag & MHD_USE_AUTO) ? "internal thread pool with 'auto'" :
        0 != (poll_flag & MHD_USE_POLL) ? "internal thread pool with poll()" :
	0 != (poll_flag & MHD_USE_EPOLL) ? "internal thread pool with epoll" : "internal thread pool with select()");
  MHD_stop_daemon (d);
  if (cbc.pos != strlen ("/hello_world"))
    return 64;
  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
    return 128;
  return 0;
}
static int
testLongUrlGet ()
{
  struct MHD_Daemon *d;
  CURL *c;
  char buf[2048];
  struct CBC cbc;
  char *url;
  long code;
  int port;

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    {
      port = 1330;
      if (oneone)
        port += 5;
    }
  cbc.buf = buf;
  cbc.size = 2048;
  cbc.pos = 0;
  d = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */ ,
                        port,
                        &apc_all,
                        NULL,
                        &ahc_echo,
                        "GET",
                        MHD_OPTION_CONNECTION_MEMORY_LIMIT,
                        (size_t) (VERY_LONG / 2), MHD_OPTION_END);
  if (d == NULL)
    return 1;
  if (0 == port)
    {
      const union MHD_DaemonInfo *dinfo;
      dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
      if (NULL == dinfo || 0 == dinfo->port)
        { MHD_stop_daemon (d); return 32; }
      port = (int)dinfo->port;
    }
  c = curl_easy_init ();
  url = malloc (VERY_LONG);
  if (url == NULL)
    {
	MHD_stop_daemon (d);
 	return 1;
    }
  memset (url, 'a', VERY_LONG);
  url[VERY_LONG - 1] = '\0';
  memcpy (url, "http://127.0.0.1/", strlen ("http://127.0.0.1/"));
  curl_easy_setopt (c, CURLOPT_URL, url);
  curl_easy_setopt (c, CURLOPT_PORT, (long)port);
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
  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, 1L);
  if (CURLE_OK == curl_easy_perform (c))
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      free (url);
      return 2;
    }
  if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
    {
      curl_easy_cleanup (c);
      MHD_stop_daemon (d);
      free (url);
      return 4;
    }
  curl_easy_cleanup (c);
  MHD_stop_daemon (d);
  free (url);
  if (code != MHD_HTTP_URI_TOO_LONG)
    return 8;
  return 0;
}