Add stock 0.9.42 source.

This is from http://www.gnu.org/software/libmicrohttpd/ (and
was verified to match the source from a local mirror).

Bug: 23101922
Change-Id: I7efc9d5065b49b8957ce41bb6afd2ce1f39c7cac
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
new file mode 100644
index 0000000..eb165bd
--- /dev/null
+++ b/src/testcurl/Makefile.am
@@ -0,0 +1,310 @@
+# This Makefile.am is in the public domain
+SUBDIRS  = .
+
+if USE_COVERAGE
+  AM_CFLAGS = -fprofile-arcs -ftest-coverage
+endif
+
+if ENABLE_HTTPS
+  SUBDIRS += https
+endif
+
+AM_CPPFLAGS = \
+-DCPU_COUNT=$(CPU_COUNT) \
+-I$(top_srcdir) \
+-I$(top_srcdir)/src/microhttpd \
+-I$(top_srcdir)/src/include \
+$(LIBCURL_CPPFLAGS)
+
+if !HAVE_W32
+PERF_GET_CONCURRENT=perf_get_concurrent
+TEST_CONCURRENT_STOP=test_concurrent_stop
+if HAVE_CURL_BINARY
+CURL_FORK_TEST = test_get_response_cleanup
+endif
+endif
+
+if HAVE_CURL
+check_PROGRAMS = \
+  test_start_stop \
+  test_get \
+  test_get_sendfile \
+  test_urlparse \
+  test_put \
+  $(TEST_CONCURRENT_STOP) \
+  test_process_headers \
+  test_process_arguments \
+  test_parse_cookies \
+  test_large_put \
+  test_get11 \
+  test_get_sendfile11 \
+  test_put11 \
+  test_large_put11 \
+  test_long_header \
+  test_long_header11 \
+  test_get_chunked \
+  test_put_chunked \
+  test_iplimit11 \
+  test_termination \
+  test_timeout \
+  test_callback \
+  $(CURL_FORK_TEST) \
+  perf_get $(PERF_GET_CONCURRENT)
+
+if HAVE_POSIX_THREADS
+check_PROGRAMS += \
+  test_quiesce
+endif
+
+if HAVE_POSTPROCESSOR
+ check_PROGRAMS += \
+  test_post \
+  test_postform \
+  test_post_loop \
+  test_post11 \
+  test_postform11 \
+  test_post_loop11
+endif
+
+noinst_PROGRAMS = \
+  test_options
+
+if ENABLE_DAUTH
+  check_PROGRAMS += \
+	test_digestauth test_digestauth_with_arguments
+endif
+
+TESTS = $(check_PROGRAMS)
+
+noinst_LIBRARIES = libcurl_version_check.a
+endif
+
+libcurl_version_check_a_SOURCES = \
+  curl_version_check.c
+
+test_start_stop_SOURCES = \
+  test_start_stop.c
+test_start_stop_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la
+
+test_concurrent_stop_SOURCES = \
+  test_concurrent_stop.c
+test_concurrent_stop_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
+test_options_SOURCES = \
+  test_options.c
+test_options_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la
+
+test_get_SOURCES = \
+  test_get.c
+test_get_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_quiesce_SOURCES = \
+  test_quiesce.c
+test_quiesce_CFLAGS = \
+  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_quiesce_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(PTHREAD_LIBS) @LIBCURL@
+
+test_callback_SOURCES = \
+  test_callback.c
+test_callback_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+perf_get_SOURCES = \
+  perf_get.c \
+  gauger.h
+perf_get_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+perf_get_concurrent_SOURCES = \
+  perf_get_concurrent.c \
+  gauger.h
+perf_get_concurrent_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_digestauth_SOURCES = \
+  test_digestauth.c
+test_digestauth_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_digestauth_with_arguments_SOURCES = \
+  test_digestauth_with_arguments.c
+test_digestauth_with_arguments_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_get_sendfile_SOURCES = \
+  test_get_sendfile.c
+test_get_sendfile_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+test_get_sendfile_DEPENDENCIES =
+
+if HAVE_W32
+test_get_sendfile_LDADD += \
+ $(top_builddir)/src/platform/libplatform_interface.la
+test_get_sendfile_DEPENDENCIES += \
+ $(top_builddir)/src/platform/libplatform_interface.la
+endif
+
+test_urlparse_SOURCES = \
+  test_urlparse.c
+test_urlparse_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_get_response_cleanup_SOURCES = \
+  test_get_response_cleanup.c
+test_get_response_cleanup_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la
+
+test_get_chunked_SOURCES = \
+  test_get_chunked.c
+test_get_chunked_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_post_SOURCES = \
+  test_post.c
+test_post_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_process_headers_SOURCES = \
+  test_process_headers.c
+test_process_headers_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_parse_cookies_SOURCES = \
+  test_parse_cookies.c
+test_parse_cookies_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_process_arguments_SOURCES = \
+  test_process_arguments.c
+test_process_arguments_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_postform_SOURCES = \
+  test_postform.c
+test_postform_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_post_loop_SOURCES = \
+  test_post_loop.c
+test_post_loop_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_put_SOURCES = \
+  test_put.c
+test_put_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_put_chunked_SOURCES = \
+  test_put_chunked.c
+test_put_chunked_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_get11_SOURCES = \
+  test_get.c
+test_get11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_get_sendfile11_SOURCES = \
+  test_get_sendfile.c
+test_get_sendfile11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+test_get_sendfile11_DEPENDENCIES =
+
+if HAVE_W32
+test_get_sendfile11_LDADD += \
+  $(top_builddir)/src/platform/libplatform_interface.la
+test_get_sendfile11_DEPENDENCIES += \
+  $(top_builddir)/src/platform/libplatform_interface.la
+endif
+
+test_post11_SOURCES = \
+  test_post.c
+test_post11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_postform11_SOURCES = \
+  test_postform.c
+test_postform11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_post_loop11_SOURCES = \
+  test_post_loop.c
+test_post_loop11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_put11_SOURCES = \
+  test_put.c
+test_put11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_large_put_SOURCES = \
+  test_large_put.c
+test_large_put_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_large_put11_SOURCES = \
+  test_large_put.c
+test_large_put11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_long_header_SOURCES = \
+  test_long_header.c
+test_long_header_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_long_header11_SOURCES = \
+  test_long_header.c
+test_long_header11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_iplimit11_SOURCES = \
+  test_iplimit.c
+test_iplimit11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_termination_SOURCES = \
+  test_termination.c
+test_termination_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_timeout_SOURCES = \
+  test_timeout.c
+test_timeout_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
diff --git a/src/testcurl/Makefile.in b/src/testcurl/Makefile.in
new file mode 100644
index 0000000..937bf26
--- /dev/null
+++ b/src/testcurl/Makefile.in
@@ -0,0 +1,2059 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@ENABLE_HTTPS_TRUE@am__append_1 = https
+@HAVE_CURL_TRUE@check_PROGRAMS = test_start_stop$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_get$(EXEEXT) test_get_sendfile$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_urlparse$(EXEEXT) test_put$(EXEEXT) \
+@HAVE_CURL_TRUE@	$(am__EXEEXT_1) test_process_headers$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_process_arguments$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_parse_cookies$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_large_put$(EXEEXT) test_get11$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_get_sendfile11$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_put11$(EXEEXT) test_large_put11$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_long_header$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_long_header11$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_get_chunked$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_put_chunked$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_iplimit11$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_termination$(EXEEXT) \
+@HAVE_CURL_TRUE@	test_timeout$(EXEEXT) test_callback$(EXEEXT) \
+@HAVE_CURL_TRUE@	$(am__EXEEXT_2) perf_get$(EXEEXT) \
+@HAVE_CURL_TRUE@	$(am__EXEEXT_3) $(am__EXEEXT_4) \
+@HAVE_CURL_TRUE@	$(am__EXEEXT_5) $(am__EXEEXT_6)
+@HAVE_CURL_TRUE@@HAVE_POSIX_THREADS_TRUE@am__append_2 = \
+@HAVE_CURL_TRUE@@HAVE_POSIX_THREADS_TRUE@  test_quiesce
+
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@am__append_3 = \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@  test_post \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@  test_postform \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@  test_post_loop \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@  test_post11 \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@  test_postform11 \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@  test_post_loop11
+
+@HAVE_CURL_TRUE@noinst_PROGRAMS = test_options$(EXEEXT)
+@ENABLE_DAUTH_TRUE@@HAVE_CURL_TRUE@am__append_4 = \
+@ENABLE_DAUTH_TRUE@@HAVE_CURL_TRUE@	test_digestauth test_digestauth_with_arguments
+
+@HAVE_W32_TRUE@am__append_5 = \
+@HAVE_W32_TRUE@ $(top_builddir)/src/platform/libplatform_interface.la
+
+@HAVE_W32_TRUE@am__append_6 = \
+@HAVE_W32_TRUE@ $(top_builddir)/src/platform/libplatform_interface.la
+
+@HAVE_W32_TRUE@am__append_7 = \
+@HAVE_W32_TRUE@  $(top_builddir)/src/platform/libplatform_interface.la
+
+@HAVE_W32_TRUE@am__append_8 = \
+@HAVE_W32_TRUE@  $(top_builddir)/src/platform/libplatform_interface.la
+
+subdir = src/testcurl
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp $(top_srcdir)/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_check_openssl.m4 \
+	$(top_srcdir)/m4/ax_count_cpus.m4 \
+	$(top_srcdir)/m4/ax_have_epoll.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_require_defined.m4 \
+	$(top_srcdir)/m4/libcurl.m4 $(top_srcdir)/m4/libgcrypt.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/MHD_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_@AM_V@)
+am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
+am__v_AR_0 = @echo "  AR      " $@;
+am__v_AR_1 = 
+libcurl_version_check_a_AR = $(AR) $(ARFLAGS)
+libcurl_version_check_a_LIBADD =
+am_libcurl_version_check_a_OBJECTS = curl_version_check.$(OBJEXT)
+libcurl_version_check_a_OBJECTS =  \
+	$(am_libcurl_version_check_a_OBJECTS)
+@HAVE_W32_FALSE@am__EXEEXT_1 = test_concurrent_stop$(EXEEXT)
+@HAVE_CURL_BINARY_TRUE@@HAVE_W32_FALSE@am__EXEEXT_2 = test_get_response_cleanup$(EXEEXT)
+@HAVE_W32_FALSE@am__EXEEXT_3 = perf_get_concurrent$(EXEEXT)
+@HAVE_CURL_TRUE@@HAVE_POSIX_THREADS_TRUE@am__EXEEXT_4 = test_quiesce$(EXEEXT)
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@am__EXEEXT_5 =  \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@	test_post$(EXEEXT) \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@	test_postform$(EXEEXT) \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@	test_post_loop$(EXEEXT) \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@	test_post11$(EXEEXT) \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@	test_postform11$(EXEEXT) \
+@HAVE_CURL_TRUE@@HAVE_POSTPROCESSOR_TRUE@	test_post_loop11$(EXEEXT)
+@ENABLE_DAUTH_TRUE@@HAVE_CURL_TRUE@am__EXEEXT_6 =  \
+@ENABLE_DAUTH_TRUE@@HAVE_CURL_TRUE@	test_digestauth$(EXEEXT) \
+@ENABLE_DAUTH_TRUE@@HAVE_CURL_TRUE@	test_digestauth_with_arguments$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+am_perf_get_OBJECTS = perf_get.$(OBJEXT)
+perf_get_OBJECTS = $(am_perf_get_OBJECTS)
+perf_get_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am_perf_get_concurrent_OBJECTS = perf_get_concurrent.$(OBJEXT)
+perf_get_concurrent_OBJECTS = $(am_perf_get_concurrent_OBJECTS)
+perf_get_concurrent_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_callback_OBJECTS = test_callback.$(OBJEXT)
+test_callback_OBJECTS = $(am_test_callback_OBJECTS)
+test_callback_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_concurrent_stop_OBJECTS = test_concurrent_stop.$(OBJEXT)
+test_concurrent_stop_OBJECTS = $(am_test_concurrent_stop_OBJECTS)
+test_concurrent_stop_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_digestauth_OBJECTS = test_digestauth.$(OBJEXT)
+test_digestauth_OBJECTS = $(am_test_digestauth_OBJECTS)
+test_digestauth_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_digestauth_with_arguments_OBJECTS =  \
+	test_digestauth_with_arguments.$(OBJEXT)
+test_digestauth_with_arguments_OBJECTS =  \
+	$(am_test_digestauth_with_arguments_OBJECTS)
+test_digestauth_with_arguments_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_get_OBJECTS = test_get.$(OBJEXT)
+test_get_OBJECTS = $(am_test_get_OBJECTS)
+test_get_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_get11_OBJECTS = test_get.$(OBJEXT)
+test_get11_OBJECTS = $(am_test_get11_OBJECTS)
+test_get11_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_get_chunked_OBJECTS = test_get_chunked.$(OBJEXT)
+test_get_chunked_OBJECTS = $(am_test_get_chunked_OBJECTS)
+test_get_chunked_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_get_response_cleanup_OBJECTS =  \
+	test_get_response_cleanup.$(OBJEXT)
+test_get_response_cleanup_OBJECTS =  \
+	$(am_test_get_response_cleanup_OBJECTS)
+test_get_response_cleanup_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_get_sendfile_OBJECTS = test_get_sendfile.$(OBJEXT)
+test_get_sendfile_OBJECTS = $(am_test_get_sendfile_OBJECTS)
+am_test_get_sendfile11_OBJECTS = test_get_sendfile.$(OBJEXT)
+test_get_sendfile11_OBJECTS = $(am_test_get_sendfile11_OBJECTS)
+am_test_iplimit11_OBJECTS = test_iplimit.$(OBJEXT)
+test_iplimit11_OBJECTS = $(am_test_iplimit11_OBJECTS)
+test_iplimit11_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_large_put_OBJECTS = test_large_put.$(OBJEXT)
+test_large_put_OBJECTS = $(am_test_large_put_OBJECTS)
+test_large_put_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_large_put11_OBJECTS = test_large_put.$(OBJEXT)
+test_large_put11_OBJECTS = $(am_test_large_put11_OBJECTS)
+test_large_put11_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_long_header_OBJECTS = test_long_header.$(OBJEXT)
+test_long_header_OBJECTS = $(am_test_long_header_OBJECTS)
+test_long_header_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_long_header11_OBJECTS = test_long_header.$(OBJEXT)
+test_long_header11_OBJECTS = $(am_test_long_header11_OBJECTS)
+test_long_header11_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_options_OBJECTS = test_options.$(OBJEXT)
+test_options_OBJECTS = $(am_test_options_OBJECTS)
+test_options_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_parse_cookies_OBJECTS = test_parse_cookies.$(OBJEXT)
+test_parse_cookies_OBJECTS = $(am_test_parse_cookies_OBJECTS)
+test_parse_cookies_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_post_OBJECTS = test_post.$(OBJEXT)
+test_post_OBJECTS = $(am_test_post_OBJECTS)
+test_post_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_post11_OBJECTS = test_post.$(OBJEXT)
+test_post11_OBJECTS = $(am_test_post11_OBJECTS)
+test_post11_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_post_loop_OBJECTS = test_post_loop.$(OBJEXT)
+test_post_loop_OBJECTS = $(am_test_post_loop_OBJECTS)
+test_post_loop_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_post_loop11_OBJECTS = test_post_loop.$(OBJEXT)
+test_post_loop11_OBJECTS = $(am_test_post_loop11_OBJECTS)
+test_post_loop11_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_postform_OBJECTS = test_postform.$(OBJEXT)
+test_postform_OBJECTS = $(am_test_postform_OBJECTS)
+test_postform_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_postform11_OBJECTS = test_postform.$(OBJEXT)
+test_postform11_OBJECTS = $(am_test_postform11_OBJECTS)
+test_postform11_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_process_arguments_OBJECTS = test_process_arguments.$(OBJEXT)
+test_process_arguments_OBJECTS = $(am_test_process_arguments_OBJECTS)
+test_process_arguments_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_process_headers_OBJECTS = test_process_headers.$(OBJEXT)
+test_process_headers_OBJECTS = $(am_test_process_headers_OBJECTS)
+test_process_headers_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_put_OBJECTS = test_put.$(OBJEXT)
+test_put_OBJECTS = $(am_test_put_OBJECTS)
+test_put_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_put11_OBJECTS = test_put.$(OBJEXT)
+test_put11_OBJECTS = $(am_test_put11_OBJECTS)
+test_put11_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_put_chunked_OBJECTS = test_put_chunked.$(OBJEXT)
+test_put_chunked_OBJECTS = $(am_test_put_chunked_OBJECTS)
+test_put_chunked_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_quiesce_OBJECTS = test_quiesce-test_quiesce.$(OBJEXT)
+test_quiesce_OBJECTS = $(am_test_quiesce_OBJECTS)
+am__DEPENDENCIES_1 =
+test_quiesce_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+	$(am__DEPENDENCIES_1)
+test_quiesce_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_quiesce_CFLAGS) \
+	$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_test_start_stop_OBJECTS = test_start_stop.$(OBJEXT)
+test_start_stop_OBJECTS = $(am_test_start_stop_OBJECTS)
+test_start_stop_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_termination_OBJECTS = test_termination.$(OBJEXT)
+test_termination_OBJECTS = $(am_test_termination_OBJECTS)
+test_termination_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_timeout_OBJECTS = test_timeout.$(OBJEXT)
+test_timeout_OBJECTS = $(am_test_timeout_OBJECTS)
+test_timeout_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+am_test_urlparse_OBJECTS = test_urlparse.$(OBJEXT)
+test_urlparse_OBJECTS = $(am_test_urlparse_OBJECTS)
+test_urlparse_DEPENDENCIES =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(libcurl_version_check_a_SOURCES) $(perf_get_SOURCES) \
+	$(perf_get_concurrent_SOURCES) $(test_callback_SOURCES) \
+	$(test_concurrent_stop_SOURCES) $(test_digestauth_SOURCES) \
+	$(test_digestauth_with_arguments_SOURCES) $(test_get_SOURCES) \
+	$(test_get11_SOURCES) $(test_get_chunked_SOURCES) \
+	$(test_get_response_cleanup_SOURCES) \
+	$(test_get_sendfile_SOURCES) $(test_get_sendfile11_SOURCES) \
+	$(test_iplimit11_SOURCES) $(test_large_put_SOURCES) \
+	$(test_large_put11_SOURCES) $(test_long_header_SOURCES) \
+	$(test_long_header11_SOURCES) $(test_options_SOURCES) \
+	$(test_parse_cookies_SOURCES) $(test_post_SOURCES) \
+	$(test_post11_SOURCES) $(test_post_loop_SOURCES) \
+	$(test_post_loop11_SOURCES) $(test_postform_SOURCES) \
+	$(test_postform11_SOURCES) $(test_process_arguments_SOURCES) \
+	$(test_process_headers_SOURCES) $(test_put_SOURCES) \
+	$(test_put11_SOURCES) $(test_put_chunked_SOURCES) \
+	$(test_quiesce_SOURCES) $(test_start_stop_SOURCES) \
+	$(test_termination_SOURCES) $(test_timeout_SOURCES) \
+	$(test_urlparse_SOURCES)
+DIST_SOURCES = $(libcurl_version_check_a_SOURCES) $(perf_get_SOURCES) \
+	$(perf_get_concurrent_SOURCES) $(test_callback_SOURCES) \
+	$(test_concurrent_stop_SOURCES) $(test_digestauth_SOURCES) \
+	$(test_digestauth_with_arguments_SOURCES) $(test_get_SOURCES) \
+	$(test_get11_SOURCES) $(test_get_chunked_SOURCES) \
+	$(test_get_response_cleanup_SOURCES) \
+	$(test_get_sendfile_SOURCES) $(test_get_sendfile11_SOURCES) \
+	$(test_iplimit11_SOURCES) $(test_large_put_SOURCES) \
+	$(test_large_put11_SOURCES) $(test_long_header_SOURCES) \
+	$(test_long_header11_SOURCES) $(test_options_SOURCES) \
+	$(test_parse_cookies_SOURCES) $(test_post_SOURCES) \
+	$(test_post11_SOURCES) $(test_post_loop_SOURCES) \
+	$(test_post_loop11_SOURCES) $(test_postform_SOURCES) \
+	$(test_postform11_SOURCES) $(test_process_arguments_SOURCES) \
+	$(test_process_headers_SOURCES) $(test_put_SOURCES) \
+	$(test_put11_SOURCES) $(test_put_chunked_SOURCES) \
+	$(test_quiesce_SOURCES) $(test_start_stop_SOURCES) \
+	$(test_termination_SOURCES) $(test_timeout_SOURCES) \
+	$(test_urlparse_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	check recheck distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DIST_SUBDIRS = . https
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPU_COUNT = @CPU_COUNT@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_CPPFLAGS = @GNUTLS_CPPFLAGS@
+GNUTLS_LDFLAGS = @GNUTLS_LDFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+HAVE_CURL_BINARY = @HAVE_CURL_BINARY@
+HAVE_MAKEINFO_BINARY = @HAVE_MAKEINFO_BINARY@
+HIDDEN_VISIBILITY_CFLAGS = @HIDDEN_VISIBILITY_CFLAGS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBCURL = @LIBCURL@
+LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSPDY_VERSION_AGE = @LIBSPDY_VERSION_AGE@
+LIBSPDY_VERSION_CURRENT = @LIBSPDY_VERSION_CURRENT@
+LIBSPDY_VERSION_REVISION = @LIBSPDY_VERSION_REVISION@
+LIBTOOL = @LIBTOOL@
+LIB_VERSION_AGE = @LIB_VERSION_AGE@
+LIB_VERSION_CURRENT = @LIB_VERSION_CURRENT@
+LIB_VERSION_REVISION = @LIB_VERSION_REVISION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MHD_LIBDEPS = @MHD_LIBDEPS@
+MHD_LIBDEPS_PKGCFG = @MHD_LIBDEPS_PKGCFG@
+MHD_LIB_CFLAGS = @MHD_LIB_CFLAGS@
+MHD_LIB_CPPFLAGS = @MHD_LIB_CPPFLAGS@
+MHD_LIB_LDFLAGS = @MHD_LIB_LDFLAGS@
+MHD_REQ_PRIVATE = @MHD_REQ_PRIVATE@
+MKDIR_P = @MKDIR_P@
+MS_LIB_TOOL = @MS_LIB_TOOL@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
+OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_SUBMINOR = @PACKAGE_VERSION_SUBMINOR@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPDY_LIBDEPS = @SPDY_LIBDEPS@
+SPDY_LIB_CFLAGS = @SPDY_LIB_CFLAGS@
+SPDY_LIB_CPPFLAGS = @SPDY_LIB_CPPFLAGS@
+SPDY_LIB_LDFLAGS = @SPDY_LIB_LDFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+_libcurl_config = @_libcurl_config@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+have_socat = @have_socat@
+have_zzuf = @have_zzuf@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_cv_objdir = @lt_cv_objdir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# This Makefile.am is in the public domain
+SUBDIRS = . $(am__append_1)
+@USE_COVERAGE_TRUE@AM_CFLAGS = -fprofile-arcs -ftest-coverage
+AM_CPPFLAGS = \
+-DCPU_COUNT=$(CPU_COUNT) \
+-I$(top_srcdir) \
+-I$(top_srcdir)/src/microhttpd \
+-I$(top_srcdir)/src/include \
+$(LIBCURL_CPPFLAGS)
+
+@HAVE_W32_FALSE@PERF_GET_CONCURRENT = perf_get_concurrent
+@HAVE_W32_FALSE@TEST_CONCURRENT_STOP = test_concurrent_stop
+@HAVE_CURL_BINARY_TRUE@@HAVE_W32_FALSE@CURL_FORK_TEST = test_get_response_cleanup
+@HAVE_CURL_TRUE@TESTS = $(check_PROGRAMS)
+@HAVE_CURL_TRUE@noinst_LIBRARIES = libcurl_version_check.a
+libcurl_version_check_a_SOURCES = \
+  curl_version_check.c
+
+test_start_stop_SOURCES = \
+  test_start_stop.c
+
+test_start_stop_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la
+
+test_concurrent_stop_SOURCES = \
+  test_concurrent_stop.c
+
+test_concurrent_stop_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ @LIBCURL@
+
+test_options_SOURCES = \
+  test_options.c
+
+test_options_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la
+
+test_get_SOURCES = \
+  test_get.c
+
+test_get_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_quiesce_SOURCES = \
+  test_quiesce.c
+
+test_quiesce_CFLAGS = \
+  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+
+test_quiesce_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(PTHREAD_LIBS) @LIBCURL@
+
+test_callback_SOURCES = \
+  test_callback.c
+
+test_callback_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+perf_get_SOURCES = \
+  perf_get.c \
+  gauger.h
+
+perf_get_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+perf_get_concurrent_SOURCES = \
+  perf_get_concurrent.c \
+  gauger.h
+
+perf_get_concurrent_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_digestauth_SOURCES = \
+  test_digestauth.c
+
+test_digestauth_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_digestauth_with_arguments_SOURCES = \
+  test_digestauth_with_arguments.c
+
+test_digestauth_with_arguments_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_get_sendfile_SOURCES = \
+  test_get_sendfile.c
+
+test_get_sendfile_LDADD =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la @LIBCURL@ \
+	$(am__append_5)
+test_get_sendfile_DEPENDENCIES = $(am__append_6)
+test_urlparse_SOURCES = \
+  test_urlparse.c
+
+test_urlparse_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_get_response_cleanup_SOURCES = \
+  test_get_response_cleanup.c
+
+test_get_response_cleanup_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la
+
+test_get_chunked_SOURCES = \
+  test_get_chunked.c
+
+test_get_chunked_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_post_SOURCES = \
+  test_post.c
+
+test_post_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_process_headers_SOURCES = \
+  test_process_headers.c
+
+test_process_headers_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_parse_cookies_SOURCES = \
+  test_parse_cookies.c
+
+test_parse_cookies_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_process_arguments_SOURCES = \
+  test_process_arguments.c
+
+test_process_arguments_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_postform_SOURCES = \
+  test_postform.c
+
+test_postform_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_post_loop_SOURCES = \
+  test_post_loop.c
+
+test_post_loop_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_put_SOURCES = \
+  test_put.c
+
+test_put_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_put_chunked_SOURCES = \
+  test_put_chunked.c
+
+test_put_chunked_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_get11_SOURCES = \
+  test_get.c
+
+test_get11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_get_sendfile11_SOURCES = \
+  test_get_sendfile.c
+
+test_get_sendfile11_LDADD =  \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la @LIBCURL@ \
+	$(am__append_7)
+test_get_sendfile11_DEPENDENCIES = $(am__append_8)
+test_post11_SOURCES = \
+  test_post.c
+
+test_post11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_postform11_SOURCES = \
+  test_postform.c
+
+test_postform11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_post_loop11_SOURCES = \
+  test_post_loop.c
+
+test_post_loop11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_put11_SOURCES = \
+  test_put.c
+
+test_put11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_large_put_SOURCES = \
+  test_large_put.c
+
+test_large_put_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_large_put11_SOURCES = \
+  test_large_put.c
+
+test_large_put11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_long_header_SOURCES = \
+  test_long_header.c
+
+test_long_header_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_long_header11_SOURCES = \
+  test_long_header.c
+
+test_long_header11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_iplimit11_SOURCES = \
+  test_iplimit.c
+
+test_iplimit11_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_termination_SOURCES = \
+  test_termination.c
+
+test_termination_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+test_timeout_SOURCES = \
+  test_timeout.c
+
+test_timeout_LDADD = \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  @LIBCURL@
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/testcurl/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/testcurl/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+libcurl_version_check.a: $(libcurl_version_check_a_OBJECTS) $(libcurl_version_check_a_DEPENDENCIES) $(EXTRA_libcurl_version_check_a_DEPENDENCIES) 
+	$(AM_V_at)-rm -f libcurl_version_check.a
+	$(AM_V_AR)$(libcurl_version_check_a_AR) libcurl_version_check.a $(libcurl_version_check_a_OBJECTS) $(libcurl_version_check_a_LIBADD)
+	$(AM_V_at)$(RANLIB) libcurl_version_check.a
+
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+clean-noinstPROGRAMS:
+	@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+perf_get$(EXEEXT): $(perf_get_OBJECTS) $(perf_get_DEPENDENCIES) $(EXTRA_perf_get_DEPENDENCIES) 
+	@rm -f perf_get$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(perf_get_OBJECTS) $(perf_get_LDADD) $(LIBS)
+
+perf_get_concurrent$(EXEEXT): $(perf_get_concurrent_OBJECTS) $(perf_get_concurrent_DEPENDENCIES) $(EXTRA_perf_get_concurrent_DEPENDENCIES) 
+	@rm -f perf_get_concurrent$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(perf_get_concurrent_OBJECTS) $(perf_get_concurrent_LDADD) $(LIBS)
+
+test_callback$(EXEEXT): $(test_callback_OBJECTS) $(test_callback_DEPENDENCIES) $(EXTRA_test_callback_DEPENDENCIES) 
+	@rm -f test_callback$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_callback_OBJECTS) $(test_callback_LDADD) $(LIBS)
+
+test_concurrent_stop$(EXEEXT): $(test_concurrent_stop_OBJECTS) $(test_concurrent_stop_DEPENDENCIES) $(EXTRA_test_concurrent_stop_DEPENDENCIES) 
+	@rm -f test_concurrent_stop$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_concurrent_stop_OBJECTS) $(test_concurrent_stop_LDADD) $(LIBS)
+
+test_digestauth$(EXEEXT): $(test_digestauth_OBJECTS) $(test_digestauth_DEPENDENCIES) $(EXTRA_test_digestauth_DEPENDENCIES) 
+	@rm -f test_digestauth$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_digestauth_OBJECTS) $(test_digestauth_LDADD) $(LIBS)
+
+test_digestauth_with_arguments$(EXEEXT): $(test_digestauth_with_arguments_OBJECTS) $(test_digestauth_with_arguments_DEPENDENCIES) $(EXTRA_test_digestauth_with_arguments_DEPENDENCIES) 
+	@rm -f test_digestauth_with_arguments$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_digestauth_with_arguments_OBJECTS) $(test_digestauth_with_arguments_LDADD) $(LIBS)
+
+test_get$(EXEEXT): $(test_get_OBJECTS) $(test_get_DEPENDENCIES) $(EXTRA_test_get_DEPENDENCIES) 
+	@rm -f test_get$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_get_OBJECTS) $(test_get_LDADD) $(LIBS)
+
+test_get11$(EXEEXT): $(test_get11_OBJECTS) $(test_get11_DEPENDENCIES) $(EXTRA_test_get11_DEPENDENCIES) 
+	@rm -f test_get11$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_get11_OBJECTS) $(test_get11_LDADD) $(LIBS)
+
+test_get_chunked$(EXEEXT): $(test_get_chunked_OBJECTS) $(test_get_chunked_DEPENDENCIES) $(EXTRA_test_get_chunked_DEPENDENCIES) 
+	@rm -f test_get_chunked$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_get_chunked_OBJECTS) $(test_get_chunked_LDADD) $(LIBS)
+
+test_get_response_cleanup$(EXEEXT): $(test_get_response_cleanup_OBJECTS) $(test_get_response_cleanup_DEPENDENCIES) $(EXTRA_test_get_response_cleanup_DEPENDENCIES) 
+	@rm -f test_get_response_cleanup$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_get_response_cleanup_OBJECTS) $(test_get_response_cleanup_LDADD) $(LIBS)
+
+test_get_sendfile$(EXEEXT): $(test_get_sendfile_OBJECTS) $(test_get_sendfile_DEPENDENCIES) $(EXTRA_test_get_sendfile_DEPENDENCIES) 
+	@rm -f test_get_sendfile$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_get_sendfile_OBJECTS) $(test_get_sendfile_LDADD) $(LIBS)
+
+test_get_sendfile11$(EXEEXT): $(test_get_sendfile11_OBJECTS) $(test_get_sendfile11_DEPENDENCIES) $(EXTRA_test_get_sendfile11_DEPENDENCIES) 
+	@rm -f test_get_sendfile11$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_get_sendfile11_OBJECTS) $(test_get_sendfile11_LDADD) $(LIBS)
+
+test_iplimit11$(EXEEXT): $(test_iplimit11_OBJECTS) $(test_iplimit11_DEPENDENCIES) $(EXTRA_test_iplimit11_DEPENDENCIES) 
+	@rm -f test_iplimit11$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_iplimit11_OBJECTS) $(test_iplimit11_LDADD) $(LIBS)
+
+test_large_put$(EXEEXT): $(test_large_put_OBJECTS) $(test_large_put_DEPENDENCIES) $(EXTRA_test_large_put_DEPENDENCIES) 
+	@rm -f test_large_put$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_large_put_OBJECTS) $(test_large_put_LDADD) $(LIBS)
+
+test_large_put11$(EXEEXT): $(test_large_put11_OBJECTS) $(test_large_put11_DEPENDENCIES) $(EXTRA_test_large_put11_DEPENDENCIES) 
+	@rm -f test_large_put11$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_large_put11_OBJECTS) $(test_large_put11_LDADD) $(LIBS)
+
+test_long_header$(EXEEXT): $(test_long_header_OBJECTS) $(test_long_header_DEPENDENCIES) $(EXTRA_test_long_header_DEPENDENCIES) 
+	@rm -f test_long_header$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_long_header_OBJECTS) $(test_long_header_LDADD) $(LIBS)
+
+test_long_header11$(EXEEXT): $(test_long_header11_OBJECTS) $(test_long_header11_DEPENDENCIES) $(EXTRA_test_long_header11_DEPENDENCIES) 
+	@rm -f test_long_header11$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_long_header11_OBJECTS) $(test_long_header11_LDADD) $(LIBS)
+
+test_options$(EXEEXT): $(test_options_OBJECTS) $(test_options_DEPENDENCIES) $(EXTRA_test_options_DEPENDENCIES) 
+	@rm -f test_options$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_options_OBJECTS) $(test_options_LDADD) $(LIBS)
+
+test_parse_cookies$(EXEEXT): $(test_parse_cookies_OBJECTS) $(test_parse_cookies_DEPENDENCIES) $(EXTRA_test_parse_cookies_DEPENDENCIES) 
+	@rm -f test_parse_cookies$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_parse_cookies_OBJECTS) $(test_parse_cookies_LDADD) $(LIBS)
+
+test_post$(EXEEXT): $(test_post_OBJECTS) $(test_post_DEPENDENCIES) $(EXTRA_test_post_DEPENDENCIES) 
+	@rm -f test_post$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_post_OBJECTS) $(test_post_LDADD) $(LIBS)
+
+test_post11$(EXEEXT): $(test_post11_OBJECTS) $(test_post11_DEPENDENCIES) $(EXTRA_test_post11_DEPENDENCIES) 
+	@rm -f test_post11$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_post11_OBJECTS) $(test_post11_LDADD) $(LIBS)
+
+test_post_loop$(EXEEXT): $(test_post_loop_OBJECTS) $(test_post_loop_DEPENDENCIES) $(EXTRA_test_post_loop_DEPENDENCIES) 
+	@rm -f test_post_loop$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_post_loop_OBJECTS) $(test_post_loop_LDADD) $(LIBS)
+
+test_post_loop11$(EXEEXT): $(test_post_loop11_OBJECTS) $(test_post_loop11_DEPENDENCIES) $(EXTRA_test_post_loop11_DEPENDENCIES) 
+	@rm -f test_post_loop11$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_post_loop11_OBJECTS) $(test_post_loop11_LDADD) $(LIBS)
+
+test_postform$(EXEEXT): $(test_postform_OBJECTS) $(test_postform_DEPENDENCIES) $(EXTRA_test_postform_DEPENDENCIES) 
+	@rm -f test_postform$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_postform_OBJECTS) $(test_postform_LDADD) $(LIBS)
+
+test_postform11$(EXEEXT): $(test_postform11_OBJECTS) $(test_postform11_DEPENDENCIES) $(EXTRA_test_postform11_DEPENDENCIES) 
+	@rm -f test_postform11$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_postform11_OBJECTS) $(test_postform11_LDADD) $(LIBS)
+
+test_process_arguments$(EXEEXT): $(test_process_arguments_OBJECTS) $(test_process_arguments_DEPENDENCIES) $(EXTRA_test_process_arguments_DEPENDENCIES) 
+	@rm -f test_process_arguments$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_process_arguments_OBJECTS) $(test_process_arguments_LDADD) $(LIBS)
+
+test_process_headers$(EXEEXT): $(test_process_headers_OBJECTS) $(test_process_headers_DEPENDENCIES) $(EXTRA_test_process_headers_DEPENDENCIES) 
+	@rm -f test_process_headers$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_process_headers_OBJECTS) $(test_process_headers_LDADD) $(LIBS)
+
+test_put$(EXEEXT): $(test_put_OBJECTS) $(test_put_DEPENDENCIES) $(EXTRA_test_put_DEPENDENCIES) 
+	@rm -f test_put$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_put_OBJECTS) $(test_put_LDADD) $(LIBS)
+
+test_put11$(EXEEXT): $(test_put11_OBJECTS) $(test_put11_DEPENDENCIES) $(EXTRA_test_put11_DEPENDENCIES) 
+	@rm -f test_put11$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_put11_OBJECTS) $(test_put11_LDADD) $(LIBS)
+
+test_put_chunked$(EXEEXT): $(test_put_chunked_OBJECTS) $(test_put_chunked_DEPENDENCIES) $(EXTRA_test_put_chunked_DEPENDENCIES) 
+	@rm -f test_put_chunked$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_put_chunked_OBJECTS) $(test_put_chunked_LDADD) $(LIBS)
+
+test_quiesce$(EXEEXT): $(test_quiesce_OBJECTS) $(test_quiesce_DEPENDENCIES) $(EXTRA_test_quiesce_DEPENDENCIES) 
+	@rm -f test_quiesce$(EXEEXT)
+	$(AM_V_CCLD)$(test_quiesce_LINK) $(test_quiesce_OBJECTS) $(test_quiesce_LDADD) $(LIBS)
+
+test_start_stop$(EXEEXT): $(test_start_stop_OBJECTS) $(test_start_stop_DEPENDENCIES) $(EXTRA_test_start_stop_DEPENDENCIES) 
+	@rm -f test_start_stop$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_start_stop_OBJECTS) $(test_start_stop_LDADD) $(LIBS)
+
+test_termination$(EXEEXT): $(test_termination_OBJECTS) $(test_termination_DEPENDENCIES) $(EXTRA_test_termination_DEPENDENCIES) 
+	@rm -f test_termination$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_termination_OBJECTS) $(test_termination_LDADD) $(LIBS)
+
+test_timeout$(EXEEXT): $(test_timeout_OBJECTS) $(test_timeout_DEPENDENCIES) $(EXTRA_test_timeout_DEPENDENCIES) 
+	@rm -f test_timeout$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_timeout_OBJECTS) $(test_timeout_LDADD) $(LIBS)
+
+test_urlparse$(EXEEXT): $(test_urlparse_OBJECTS) $(test_urlparse_DEPENDENCIES) $(EXTRA_test_urlparse_DEPENDENCIES) 
+	@rm -f test_urlparse$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_urlparse_OBJECTS) $(test_urlparse_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curl_version_check.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf_get.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/perf_get_concurrent.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_callback.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_concurrent_stop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_digestauth.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_digestauth_with_arguments.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_get.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_get_chunked.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_get_response_cleanup.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_get_sendfile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_iplimit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_large_put.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_long_header.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_options.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_parse_cookies.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_post.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_post_loop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_postform.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_process_arguments.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_process_headers.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_put.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_put_chunked.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_quiesce-test_quiesce.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_start_stop.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_termination.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_timeout.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_urlparse.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+test_quiesce-test_quiesce.o: test_quiesce.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_quiesce_CFLAGS) $(CFLAGS) -MT test_quiesce-test_quiesce.o -MD -MP -MF $(DEPDIR)/test_quiesce-test_quiesce.Tpo -c -o test_quiesce-test_quiesce.o `test -f 'test_quiesce.c' || echo '$(srcdir)/'`test_quiesce.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_quiesce-test_quiesce.Tpo $(DEPDIR)/test_quiesce-test_quiesce.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test_quiesce.c' object='test_quiesce-test_quiesce.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_quiesce_CFLAGS) $(CFLAGS) -c -o test_quiesce-test_quiesce.o `test -f 'test_quiesce.c' || echo '$(srcdir)/'`test_quiesce.c
+
+test_quiesce-test_quiesce.obj: test_quiesce.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_quiesce_CFLAGS) $(CFLAGS) -MT test_quiesce-test_quiesce.obj -MD -MP -MF $(DEPDIR)/test_quiesce-test_quiesce.Tpo -c -o test_quiesce-test_quiesce.obj `if test -f 'test_quiesce.c'; then $(CYGPATH_W) 'test_quiesce.c'; else $(CYGPATH_W) '$(srcdir)/test_quiesce.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_quiesce-test_quiesce.Tpo $(DEPDIR)/test_quiesce-test_quiesce.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test_quiesce.c' object='test_quiesce-test_quiesce.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_quiesce_CFLAGS) $(CFLAGS) -c -o test_quiesce-test_quiesce.obj `if test -f 'test_quiesce.c'; then $(CYGPATH_W) 'test_quiesce.c'; else $(CYGPATH_W) '$(srcdir)/test_quiesce.c'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test_start_stop.log: test_start_stop$(EXEEXT)
+	@p='test_start_stop$(EXEEXT)'; \
+	b='test_start_stop'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_get.log: test_get$(EXEEXT)
+	@p='test_get$(EXEEXT)'; \
+	b='test_get'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_get_sendfile.log: test_get_sendfile$(EXEEXT)
+	@p='test_get_sendfile$(EXEEXT)'; \
+	b='test_get_sendfile'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_urlparse.log: test_urlparse$(EXEEXT)
+	@p='test_urlparse$(EXEEXT)'; \
+	b='test_urlparse'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_put.log: test_put$(EXEEXT)
+	@p='test_put$(EXEEXT)'; \
+	b='test_put'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_concurrent_stop.log: test_concurrent_stop$(EXEEXT)
+	@p='test_concurrent_stop$(EXEEXT)'; \
+	b='test_concurrent_stop'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_process_headers.log: test_process_headers$(EXEEXT)
+	@p='test_process_headers$(EXEEXT)'; \
+	b='test_process_headers'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_process_arguments.log: test_process_arguments$(EXEEXT)
+	@p='test_process_arguments$(EXEEXT)'; \
+	b='test_process_arguments'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_parse_cookies.log: test_parse_cookies$(EXEEXT)
+	@p='test_parse_cookies$(EXEEXT)'; \
+	b='test_parse_cookies'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_large_put.log: test_large_put$(EXEEXT)
+	@p='test_large_put$(EXEEXT)'; \
+	b='test_large_put'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_get11.log: test_get11$(EXEEXT)
+	@p='test_get11$(EXEEXT)'; \
+	b='test_get11'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_get_sendfile11.log: test_get_sendfile11$(EXEEXT)
+	@p='test_get_sendfile11$(EXEEXT)'; \
+	b='test_get_sendfile11'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_put11.log: test_put11$(EXEEXT)
+	@p='test_put11$(EXEEXT)'; \
+	b='test_put11'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_large_put11.log: test_large_put11$(EXEEXT)
+	@p='test_large_put11$(EXEEXT)'; \
+	b='test_large_put11'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_long_header.log: test_long_header$(EXEEXT)
+	@p='test_long_header$(EXEEXT)'; \
+	b='test_long_header'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_long_header11.log: test_long_header11$(EXEEXT)
+	@p='test_long_header11$(EXEEXT)'; \
+	b='test_long_header11'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_get_chunked.log: test_get_chunked$(EXEEXT)
+	@p='test_get_chunked$(EXEEXT)'; \
+	b='test_get_chunked'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_put_chunked.log: test_put_chunked$(EXEEXT)
+	@p='test_put_chunked$(EXEEXT)'; \
+	b='test_put_chunked'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_iplimit11.log: test_iplimit11$(EXEEXT)
+	@p='test_iplimit11$(EXEEXT)'; \
+	b='test_iplimit11'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_termination.log: test_termination$(EXEEXT)
+	@p='test_termination$(EXEEXT)'; \
+	b='test_termination'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_timeout.log: test_timeout$(EXEEXT)
+	@p='test_timeout$(EXEEXT)'; \
+	b='test_timeout'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_callback.log: test_callback$(EXEEXT)
+	@p='test_callback$(EXEEXT)'; \
+	b='test_callback'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_get_response_cleanup.log: test_get_response_cleanup$(EXEEXT)
+	@p='test_get_response_cleanup$(EXEEXT)'; \
+	b='test_get_response_cleanup'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+perf_get.log: perf_get$(EXEEXT)
+	@p='perf_get$(EXEEXT)'; \
+	b='perf_get'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+perf_get_concurrent.log: perf_get_concurrent$(EXEEXT)
+	@p='perf_get_concurrent$(EXEEXT)'; \
+	b='perf_get_concurrent'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_quiesce.log: test_quiesce$(EXEEXT)
+	@p='test_quiesce$(EXEEXT)'; \
+	b='test_quiesce'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_post.log: test_post$(EXEEXT)
+	@p='test_post$(EXEEXT)'; \
+	b='test_post'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_postform.log: test_postform$(EXEEXT)
+	@p='test_postform$(EXEEXT)'; \
+	b='test_postform'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_post_loop.log: test_post_loop$(EXEEXT)
+	@p='test_post_loop$(EXEEXT)'; \
+	b='test_post_loop'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_post11.log: test_post11$(EXEEXT)
+	@p='test_post11$(EXEEXT)'; \
+	b='test_post11'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_postform11.log: test_postform11$(EXEEXT)
+	@p='test_postform11$(EXEEXT)'; \
+	b='test_postform11'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_post_loop11.log: test_post_loop11$(EXEEXT)
+	@p='test_post_loop11$(EXEEXT)'; \
+	b='test_post_loop11'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_digestauth.log: test_digestauth$(EXEEXT)
+	@p='test_digestauth$(EXEEXT)'; \
+	b='test_digestauth'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_digestauth_with_arguments.log: test_digestauth_with_arguments$(EXEEXT)
+	@p='test_digestauth_with_arguments$(EXEEXT)'; \
+	b='test_digestauth_with_arguments'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@	@p='$<'; \
+@am__EXEEXT_TRUE@	$(am__set_b); \
+@am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-recursive
+all-am: Makefile $(LIBRARIES) $(PROGRAMS)
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+	clean-noinstLIBRARIES clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-TESTS check-am clean clean-checkPROGRAMS clean-generic \
+	clean-libtool clean-noinstLIBRARIES clean-noinstPROGRAMS \
+	cscopelist-am ctags ctags-am distclean distclean-compile \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs installdirs-am \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+	uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/testcurl/curl_version_check.c b/src/testcurl/curl_version_check.c
new file mode 100644
index 0000000..518cb86
--- /dev/null
+++ b/src/testcurl/curl_version_check.c
@@ -0,0 +1,176 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file curl_version_check.c
+ * @brief  verify required cURL version is available to run tests
+ * @author Sagie Amir
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+static int
+parse_version_number (const char **s)
+{
+  int i = 0;
+  char num[17];
+
+  while (i < 16 && ((**s >= '0') & (**s <= '9')))
+    {
+      num[i] = **s;
+      (*s)++;
+      i++;
+    }
+
+  num[i] = '\0';
+
+  return atoi (num);
+}
+
+const char *
+parse_version_string (const char *s, int *major, int *minor, int *micro)
+{
+  if (!s)
+    return NULL;
+  *major = parse_version_number (&s);
+  if (*s != '.')
+    return NULL;
+  s++;
+  *minor = parse_version_number (&s);
+  if (*s != '.')
+    return NULL;
+  s++;
+  *micro = parse_version_number (&s);
+  return s;
+}
+
+#if HTTPS_SUPPORT
+int
+curl_uses_nss_ssl()
+{
+  return (strstr(curl_version(), " NSS/") != NULL) ? 0 : -1;
+}
+#endif
+
+/*
+ * check local libcurl version matches required version
+ */
+int
+curl_check_version (const char *req_version)
+{
+  const char *ver;
+  const char *curl_ver;
+#if HTTPS_SUPPORT
+  const char *ssl_ver;
+  const char *req_ssl_ver;
+#endif
+
+  int loc_major, loc_minor, loc_micro;
+  int rq_major, rq_minor, rq_micro;
+
+  ver = curl_version ();
+#if HAVE_MESSAGES
+  fprintf (stderr, "curl version: %s\n", ver);
+#endif
+  /*
+   * this call relies on the cURL string to be of the exact following format :
+   * 'libcurl/7.16.4 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/0.6.5' OR
+   * 'libcurl/7.18.2 GnuTLS/2.4.0 zlib/1.2.3.3 libidn/0.6.5'
+   */
+  curl_ver = strchr (ver, '/');
+  if (curl_ver == NULL)
+    return -1;
+  curl_ver++;
+  /* Parse version numbers */
+  if ( (NULL == parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro)) ||
+       (NULL == parse_version_string (curl_ver, &loc_major, &loc_minor, &loc_micro)) )
+    return -1;
+
+  /* Compare version numbers.  */
+  if ((loc_major > rq_major
+       || (loc_major == rq_major && loc_minor > rq_minor)
+       || (loc_major == rq_major && loc_minor == rq_minor
+           && loc_micro > rq_micro) || (loc_major == rq_major
+                                        && loc_minor == rq_minor
+                                        && loc_micro == rq_micro)) == 0)
+    {
+      fprintf (stderr,
+               "Error: running curl test depends on local libcurl version > %s\n",
+               req_version);
+      return -1;
+    }
+
+  /*
+   * enforce required gnutls/openssl version.
+   * TODO use curl version string to assert use of gnutls
+   */
+#if HTTPS_SUPPORT
+  ssl_ver = strchr (curl_ver, ' ');
+  if (ssl_ver == NULL)
+    return -1;
+  ssl_ver++;
+  if (strncmp ("GnuTLS", ssl_ver, strlen ("GNUtls")) == 0)
+    {
+      ssl_ver = strchr (ssl_ver, '/');
+      req_ssl_ver = MHD_REQ_CURL_GNUTLS_VERSION;
+    }
+  else if (strncmp ("OpenSSL", ssl_ver, strlen ("OpenSSL")) == 0)
+    {
+      ssl_ver = strchr (ssl_ver, '/');
+      req_ssl_ver = MHD_REQ_CURL_OPENSSL_VERSION;
+    }
+  else if (strncmp ("NSS", ssl_ver, strlen ("NSS")) == 0)
+    {
+      ssl_ver = strchr (ssl_ver, '/');
+      req_ssl_ver = MHD_REQ_CURL_NSS_VERSION;
+    }
+  else
+    {
+      fprintf (stderr, "Error: unrecognized curl ssl library\n");
+      return -1;
+    }
+  if (ssl_ver == NULL)
+    return -1;
+  ssl_ver++;
+  if ( (NULL == parse_version_string (req_ssl_ver, &rq_major, &rq_minor, &rq_micro)) ||
+       (NULL == parse_version_string (ssl_ver, &loc_major, &loc_minor, &loc_micro)) )
+    return -1;
+
+  if ((loc_major > rq_major
+       || (loc_major == rq_major && loc_minor > rq_minor)
+       || (loc_major == rq_major && loc_minor == rq_minor
+           && loc_micro > rq_micro) || (loc_major == rq_major
+                                        && loc_minor == rq_minor
+                                        && loc_micro == rq_micro)) == 0)
+    {
+      fprintf (stderr,
+               "Error: running curl test depends on local libcurl SSL version > %s\n",
+               req_ssl_ver);
+      return -1;
+    }
+#endif
+  return 0;
+}
diff --git a/src/testcurl/gauger.h b/src/testcurl/gauger.h
new file mode 100644
index 0000000..3a0dd22
--- /dev/null
+++ b/src/testcurl/gauger.h
@@ -0,0 +1,86 @@
+/** ---------------------------------------------------------------------------
+ * This software is in the public domain, furnished "as is", without technical
+ * support, and with no warranty, express or implied, as to its usefulness for
+ * any purpose.
+ *
+ * gauger.h
+ * Interface for C programs to log remotely to a gauger server
+ *
+ * Author: Bartlomiej Polot
+ * -------------------------------------------------------------------------*/
+#ifndef __GAUGER_H__
+#define __GAUGER_H__
+
+#ifndef WINDOWS
+
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/wait.h>
+
+#define GAUGER(category, counter, value, unit)\
+{\
+    const char * __gauger_v[10];			\
+    char __gauger_s[32];\
+    pid_t __gauger_p;\
+    if(!(__gauger_p=fork())){\
+      if(!fork()){ \
+            sprintf(__gauger_s,"%Lf", (long double) (value));\
+            __gauger_v[0] = "gauger";\
+            __gauger_v[1] = "-n";\
+            __gauger_v[2] = counter;	\
+            __gauger_v[3] = "-d";\
+            __gauger_v[4] = __gauger_s;\
+            __gauger_v[5] = "-u";\
+            __gauger_v[6] = unit;	\
+            __gauger_v[7] = "-c";\
+            __gauger_v[8] = category;	\
+            __gauger_v[9] = (char *)NULL;\
+            execvp("gauger", (char*const*) __gauger_v);	\
+            _exit(1);\
+        }else{\
+            _exit(0);\
+        }\
+    }else{\
+        waitpid(__gauger_p,NULL,0);\
+    }\
+}
+
+#define GAUGER_ID(category, counter, value, unit, id)\
+{\
+    char* __gauger_v[12];\
+    char __gauger_s[32];\
+    pid_t __gauger_p;\
+    if(!(__gauger_p=fork())){\
+        if(!fork()){\
+            sprintf(__gauger_s,"%Lf", (long double) (value));\
+            __gauger_v[0] = "gauger";\
+            __gauger_v[1] = "-n";\
+            __gauger_v[2] = counter;\
+            __gauger_v[3] = "-d";\
+            __gauger_v[4] = __gauger_s;\
+            __gauger_v[5] = "-u";\
+            __gauger_v[6] = unit;\
+            __gauger_v[7] = "-i";\
+            __gauger_v[8] = id;\
+            __gauger_v[9] = "-c";\
+            __gauger_v[10] = category;\
+            __gauger_v[11] = (char *)NULL;\
+            execvp("gauger",__gauger_v);\
+            perror("gauger");\
+            _exit(1);\
+        }else{\
+            _exit(0);\
+        }\
+    }else{\
+        waitpid(__gauger_p,NULL,0);\
+    }\
+}
+
+#else
+
+#define GAUGER_ID(category, counter, value, unit, id) {}
+#define GAUGER(category, counter, value, unit) {}
+
+#endif // WINDOWS
+
+#endif
diff --git a/src/testcurl/https/Makefile.am b/src/testcurl/https/Makefile.am
new file mode 100644
index 0000000..47deb70
--- /dev/null
+++ b/src/testcurl/https/Makefile.am
@@ -0,0 +1,153 @@
+# This Makefile.am is in the public domain
+SUBDIRS = .
+
+if USE_COVERAGE
+  AM_CFLAGS = --coverage
+endif
+
+if HAVE_GNUTLS_SNI
+  TEST_HTTPS_SNI = test_https_sni
+endif
+
+if HAVE_POSIX_THREADS
+  HTTPS_PARALLEL_TESTS = test_https_get_parallel \
+  test_https_get_parallel_threads
+endif
+
+CPU_COUNT_DEF = -DCPU_COUNT=$(CPU_COUNT)
+
+AM_CPPFLAGS = \
+  -I$(top_srcdir)/src/include \
+  -I$(top_srcdir)/src/microhttpd \
+  -I$(top_srcdir)/src/platform \
+  $(LIBCURL_CPPFLAGS) $(GNUTLS_CPPFLAGS)
+
+check_PROGRAMS = \
+  test_tls_options \
+  test_tls_authentication \
+  test_https_multi_daemon \
+  test_https_get \
+  $(TEST_HTTPS_SNI) \
+  test_https_get_select \
+  $(HTTPS_PARALLEL_TESTS) \
+  test_https_session_info \
+  test_https_time_out \
+  test_empty_response
+
+EXTRA_DIST = cert.pem key.pem tls_test_keys.h tls_test_common.h \
+  host1.crt host1.key host2.crt host2.key
+
+TESTS = \
+  test_tls_options \
+  test_https_multi_daemon \
+  test_https_get \
+  $(TEST_HTTPS_SNI) \
+  test_https_get_select \
+  $(HTTPS_PARALLEL_TESTS) \
+  test_https_session_info \
+  test_https_time_out \
+  test_tls_authentication \
+  test_empty_response
+
+
+test_https_time_out_SOURCES = \
+  test_https_time_out.c \
+  tls_test_common.c
+test_https_time_out_LDADD  = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_tls_options_SOURCES = \
+  test_tls_options.c \
+  tls_test_common.c
+test_tls_options_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_get_parallel_SOURCES = \
+  test_https_get_parallel.c \
+  tls_test_common.c
+test_https_get_parallel_CPPFLAGS = \
+  $(AM_CPPFLAGS) $(CPU_COUNT_DEF)
+test_https_get_parallel_CFLAGS = \
+  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_https_get_parallel_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(PTHREAD_LIBS) $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_empty_response_SOURCES = \
+  test_empty_response.c \
+  tls_test_common.c
+test_empty_response_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_get_parallel_threads_SOURCES = \
+  test_https_get_parallel_threads.c \
+  tls_test_common.c
+test_https_get_parallel_threads_CPPFLAGS = \
+  $(AM_CPPFLAGS) $(CPU_COUNT_DEF)
+test_https_get_parallel_threads_CFLAGS = \
+  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_https_get_parallel_threads_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(PTHREAD_LIBS) $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_tls_authentication_SOURCES = \
+  test_tls_authentication.c \
+  tls_test_common.c
+test_tls_authentication_LDADD  = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_session_info_SOURCES = \
+  test_https_session_info.c \
+  tls_test_common.c
+test_https_session_info_LDADD  = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_multi_daemon_SOURCES = \
+  test_https_multi_daemon.c \
+  tls_test_common.c
+test_https_multi_daemon_LDADD  = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_get_SOURCES = \
+  test_https_get.c \
+  tls_test_common.c
+test_https_get_LDADD  = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+if HAVE_GNUTLS_SNI
+test_https_sni_SOURCES = \
+  test_https_sni.c \
+  tls_test_common.c
+test_https_sni_CPPFLAGS = \
+  $(AM_CPPFLAGS) \
+  -DABS_SRCDIR=\"$(abs_srcdir)\"
+test_https_sni_LDADD  = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+endif
+
+test_https_get_select_SOURCES = \
+  test_https_get_select.c \
+  tls_test_common.c
+test_https_get_select_LDADD  = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
diff --git a/src/testcurl/https/Makefile.in b/src/testcurl/https/Makefile.in
new file mode 100644
index 0000000..8815b21
--- /dev/null
+++ b/src/testcurl/https/Makefile.in
@@ -0,0 +1,1578 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+check_PROGRAMS = test_tls_options$(EXEEXT) \
+	test_tls_authentication$(EXEEXT) \
+	test_https_multi_daemon$(EXEEXT) test_https_get$(EXEEXT) \
+	$(am__EXEEXT_1) test_https_get_select$(EXEEXT) $(am__EXEEXT_2) \
+	test_https_session_info$(EXEEXT) test_https_time_out$(EXEEXT) \
+	test_empty_response$(EXEEXT)
+TESTS = test_tls_options$(EXEEXT) test_https_multi_daemon$(EXEEXT) \
+	test_https_get$(EXEEXT) $(am__EXEEXT_1) \
+	test_https_get_select$(EXEEXT) $(am__EXEEXT_2) \
+	test_https_session_info$(EXEEXT) test_https_time_out$(EXEEXT) \
+	test_tls_authentication$(EXEEXT) test_empty_response$(EXEEXT)
+subdir = src/testcurl/https
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/depcomp $(top_srcdir)/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
+	$(top_srcdir)/m4/ax_append_flag.m4 \
+	$(top_srcdir)/m4/ax_check_compile_flag.m4 \
+	$(top_srcdir)/m4/ax_check_link_flag.m4 \
+	$(top_srcdir)/m4/ax_check_openssl.m4 \
+	$(top_srcdir)/m4/ax_count_cpus.m4 \
+	$(top_srcdir)/m4/ax_have_epoll.m4 \
+	$(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/ax_require_defined.m4 \
+	$(top_srcdir)/m4/libcurl.m4 $(top_srcdir)/m4/libgcrypt.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/MHD_config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+@HAVE_GNUTLS_SNI_TRUE@am__EXEEXT_1 = test_https_sni$(EXEEXT)
+@HAVE_POSIX_THREADS_TRUE@am__EXEEXT_2 =  \
+@HAVE_POSIX_THREADS_TRUE@	test_https_get_parallel$(EXEEXT) \
+@HAVE_POSIX_THREADS_TRUE@	test_https_get_parallel_threads$(EXEEXT)
+am_test_empty_response_OBJECTS = test_empty_response.$(OBJEXT) \
+	tls_test_common.$(OBJEXT)
+test_empty_response_OBJECTS = $(am_test_empty_response_OBJECTS)
+am__DEPENDENCIES_1 =
+test_empty_response_DEPENDENCIES =  \
+	$(top_builddir)/src/testcurl/libcurl_version_check.a \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+am_test_https_get_OBJECTS = test_https_get.$(OBJEXT) \
+	tls_test_common.$(OBJEXT)
+test_https_get_OBJECTS = $(am_test_https_get_OBJECTS)
+test_https_get_DEPENDENCIES =  \
+	$(top_builddir)/src/testcurl/libcurl_version_check.a \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_test_https_get_parallel_OBJECTS =  \
+	test_https_get_parallel-test_https_get_parallel.$(OBJEXT) \
+	test_https_get_parallel-tls_test_common.$(OBJEXT)
+test_https_get_parallel_OBJECTS =  \
+	$(am_test_https_get_parallel_OBJECTS)
+test_https_get_parallel_DEPENDENCIES =  \
+	$(top_builddir)/src/testcurl/libcurl_version_check.a \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+test_https_get_parallel_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(test_https_get_parallel_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+am_test_https_get_parallel_threads_OBJECTS = test_https_get_parallel_threads-test_https_get_parallel_threads.$(OBJEXT) \
+	test_https_get_parallel_threads-tls_test_common.$(OBJEXT)
+test_https_get_parallel_threads_OBJECTS =  \
+	$(am_test_https_get_parallel_threads_OBJECTS)
+test_https_get_parallel_threads_DEPENDENCIES =  \
+	$(top_builddir)/src/testcurl/libcurl_version_check.a \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+test_https_get_parallel_threads_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(test_https_get_parallel_threads_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_test_https_get_select_OBJECTS = test_https_get_select.$(OBJEXT) \
+	tls_test_common.$(OBJEXT)
+test_https_get_select_OBJECTS = $(am_test_https_get_select_OBJECTS)
+test_https_get_select_DEPENDENCIES =  \
+	$(top_builddir)/src/testcurl/libcurl_version_check.a \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_test_https_multi_daemon_OBJECTS =  \
+	test_https_multi_daemon.$(OBJEXT) tls_test_common.$(OBJEXT)
+test_https_multi_daemon_OBJECTS =  \
+	$(am_test_https_multi_daemon_OBJECTS)
+test_https_multi_daemon_DEPENDENCIES =  \
+	$(top_builddir)/src/testcurl/libcurl_version_check.a \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_test_https_session_info_OBJECTS =  \
+	test_https_session_info.$(OBJEXT) tls_test_common.$(OBJEXT)
+test_https_session_info_OBJECTS =  \
+	$(am_test_https_session_info_OBJECTS)
+test_https_session_info_DEPENDENCIES =  \
+	$(top_builddir)/src/testcurl/libcurl_version_check.a \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am__test_https_sni_SOURCES_DIST = test_https_sni.c tls_test_common.c
+@HAVE_GNUTLS_SNI_TRUE@am_test_https_sni_OBJECTS =  \
+@HAVE_GNUTLS_SNI_TRUE@	test_https_sni-test_https_sni.$(OBJEXT) \
+@HAVE_GNUTLS_SNI_TRUE@	test_https_sni-tls_test_common.$(OBJEXT)
+test_https_sni_OBJECTS = $(am_test_https_sni_OBJECTS)
+@HAVE_GNUTLS_SNI_TRUE@test_https_sni_DEPENDENCIES = $(top_builddir)/src/testcurl/libcurl_version_check.a \
+@HAVE_GNUTLS_SNI_TRUE@	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+@HAVE_GNUTLS_SNI_TRUE@	$(am__DEPENDENCIES_1) \
+@HAVE_GNUTLS_SNI_TRUE@	$(am__DEPENDENCIES_1)
+am_test_https_time_out_OBJECTS = test_https_time_out.$(OBJEXT) \
+	tls_test_common.$(OBJEXT)
+test_https_time_out_OBJECTS = $(am_test_https_time_out_OBJECTS)
+test_https_time_out_DEPENDENCIES =  \
+	$(top_builddir)/src/testcurl/libcurl_version_check.a \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_test_tls_authentication_OBJECTS =  \
+	test_tls_authentication.$(OBJEXT) tls_test_common.$(OBJEXT)
+test_tls_authentication_OBJECTS =  \
+	$(am_test_tls_authentication_OBJECTS)
+test_tls_authentication_DEPENDENCIES =  \
+	$(top_builddir)/src/testcurl/libcurl_version_check.a \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_test_tls_options_OBJECTS = test_tls_options.$(OBJEXT) \
+	tls_test_common.$(OBJEXT)
+test_tls_options_OBJECTS = $(am_test_tls_options_OBJECTS)
+test_tls_options_DEPENDENCIES =  \
+	$(top_builddir)/src/testcurl/libcurl_version_check.a \
+	$(top_builddir)/src/microhttpd/libmicrohttpd.la \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(test_empty_response_SOURCES) $(test_https_get_SOURCES) \
+	$(test_https_get_parallel_SOURCES) \
+	$(test_https_get_parallel_threads_SOURCES) \
+	$(test_https_get_select_SOURCES) \
+	$(test_https_multi_daemon_SOURCES) \
+	$(test_https_session_info_SOURCES) $(test_https_sni_SOURCES) \
+	$(test_https_time_out_SOURCES) \
+	$(test_tls_authentication_SOURCES) $(test_tls_options_SOURCES)
+DIST_SOURCES = $(test_empty_response_SOURCES) \
+	$(test_https_get_SOURCES) $(test_https_get_parallel_SOURCES) \
+	$(test_https_get_parallel_threads_SOURCES) \
+	$(test_https_get_select_SOURCES) \
+	$(test_https_multi_daemon_SOURCES) \
+	$(test_https_session_info_SOURCES) \
+	$(am__test_https_sni_SOURCES_DIST) \
+	$(test_https_time_out_SOURCES) \
+	$(test_tls_authentication_SOURCES) $(test_tls_options_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	check recheck distdir
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPU_COUNT = @CPU_COUNT@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GNUTLS_CFLAGS = @GNUTLS_CFLAGS@
+GNUTLS_CPPFLAGS = @GNUTLS_CPPFLAGS@
+GNUTLS_LDFLAGS = @GNUTLS_LDFLAGS@
+GNUTLS_LIBS = @GNUTLS_LIBS@
+GREP = @GREP@
+HAVE_CURL_BINARY = @HAVE_CURL_BINARY@
+HAVE_MAKEINFO_BINARY = @HAVE_MAKEINFO_BINARY@
+HIDDEN_VISIBILITY_CFLAGS = @HIDDEN_VISIBILITY_CFLAGS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBCURL = @LIBCURL@
+LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSPDY_VERSION_AGE = @LIBSPDY_VERSION_AGE@
+LIBSPDY_VERSION_CURRENT = @LIBSPDY_VERSION_CURRENT@
+LIBSPDY_VERSION_REVISION = @LIBSPDY_VERSION_REVISION@
+LIBTOOL = @LIBTOOL@
+LIB_VERSION_AGE = @LIB_VERSION_AGE@
+LIB_VERSION_CURRENT = @LIB_VERSION_CURRENT@
+LIB_VERSION_REVISION = @LIB_VERSION_REVISION@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MHD_LIBDEPS = @MHD_LIBDEPS@
+MHD_LIBDEPS_PKGCFG = @MHD_LIBDEPS_PKGCFG@
+MHD_LIB_CFLAGS = @MHD_LIB_CFLAGS@
+MHD_LIB_CPPFLAGS = @MHD_LIB_CPPFLAGS@
+MHD_LIB_LDFLAGS = @MHD_LIB_LDFLAGS@
+MHD_REQ_PRIVATE = @MHD_REQ_PRIVATE@
+MKDIR_P = @MKDIR_P@
+MS_LIB_TOOL = @MS_LIB_TOOL@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENSSL_INCLUDES = @OPENSSL_INCLUDES@
+OPENSSL_LDFLAGS = @OPENSSL_LDFLAGS@
+OPENSSL_LIBS = @OPENSSL_LIBS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_SUBMINOR = @PACKAGE_VERSION_SUBMINOR@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SPDY_LIBDEPS = @SPDY_LIBDEPS@
+SPDY_LIB_CFLAGS = @SPDY_LIB_CFLAGS@
+SPDY_LIB_CPPFLAGS = @SPDY_LIB_CPPFLAGS@
+SPDY_LIB_LDFLAGS = @SPDY_LIB_LDFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+_libcurl_config = @_libcurl_config@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+have_socat = @have_socat@
+have_zzuf = @have_zzuf@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_cv_objdir = @lt_cv_objdir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# This Makefile.am is in the public domain
+SUBDIRS = .
+@USE_COVERAGE_TRUE@AM_CFLAGS = --coverage
+@HAVE_GNUTLS_SNI_TRUE@TEST_HTTPS_SNI = test_https_sni
+@HAVE_POSIX_THREADS_TRUE@HTTPS_PARALLEL_TESTS = test_https_get_parallel \
+@HAVE_POSIX_THREADS_TRUE@  test_https_get_parallel_threads
+
+CPU_COUNT_DEF = -DCPU_COUNT=$(CPU_COUNT)
+AM_CPPFLAGS = \
+  -I$(top_srcdir)/src/include \
+  -I$(top_srcdir)/src/microhttpd \
+  -I$(top_srcdir)/src/platform \
+  $(LIBCURL_CPPFLAGS) $(GNUTLS_CPPFLAGS)
+
+EXTRA_DIST = cert.pem key.pem tls_test_keys.h tls_test_common.h \
+  host1.crt host1.key host2.crt host2.key
+
+test_https_time_out_SOURCES = \
+  test_https_time_out.c \
+  tls_test_common.c
+
+test_https_time_out_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_tls_options_SOURCES = \
+  test_tls_options.c \
+  tls_test_common.c
+
+test_tls_options_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_get_parallel_SOURCES = \
+  test_https_get_parallel.c \
+  tls_test_common.c
+
+test_https_get_parallel_CPPFLAGS = \
+  $(AM_CPPFLAGS) $(CPU_COUNT_DEF)
+
+test_https_get_parallel_CFLAGS = \
+  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+
+test_https_get_parallel_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(PTHREAD_LIBS) $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_empty_response_SOURCES = \
+  test_empty_response.c \
+  tls_test_common.c
+
+test_empty_response_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_get_parallel_threads_SOURCES = \
+  test_https_get_parallel_threads.c \
+  tls_test_common.c
+
+test_https_get_parallel_threads_CPPFLAGS = \
+  $(AM_CPPFLAGS) $(CPU_COUNT_DEF)
+
+test_https_get_parallel_threads_CFLAGS = \
+  $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+
+test_https_get_parallel_threads_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(PTHREAD_LIBS) $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_tls_authentication_SOURCES = \
+  test_tls_authentication.c \
+  tls_test_common.c
+
+test_tls_authentication_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_session_info_SOURCES = \
+  test_https_session_info.c \
+  tls_test_common.c
+
+test_https_session_info_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_multi_daemon_SOURCES = \
+  test_https_multi_daemon.c \
+  tls_test_common.c
+
+test_https_multi_daemon_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_get_SOURCES = \
+  test_https_get.c \
+  tls_test_common.c
+
+test_https_get_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+@HAVE_GNUTLS_SNI_TRUE@test_https_sni_SOURCES = \
+@HAVE_GNUTLS_SNI_TRUE@  test_https_sni.c \
+@HAVE_GNUTLS_SNI_TRUE@  tls_test_common.c
+
+@HAVE_GNUTLS_SNI_TRUE@test_https_sni_CPPFLAGS = \
+@HAVE_GNUTLS_SNI_TRUE@  $(AM_CPPFLAGS) \
+@HAVE_GNUTLS_SNI_TRUE@  -DABS_SRCDIR=\"$(abs_srcdir)\"
+
+@HAVE_GNUTLS_SNI_TRUE@test_https_sni_LDADD = \
+@HAVE_GNUTLS_SNI_TRUE@  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+@HAVE_GNUTLS_SNI_TRUE@  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+@HAVE_GNUTLS_SNI_TRUE@  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+test_https_get_select_SOURCES = \
+  test_https_get_select.c \
+  tls_test_common.c
+
+test_https_get_select_LDADD = \
+  $(top_builddir)/src/testcurl/libcurl_version_check.a \
+  $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+  $(GNUTLS_LDFLAGS) $(GNUTLS_LIBS) @LIBGCRYPT_LIBS@ @LIBCURL@
+
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/testcurl/https/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu src/testcurl/https/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+
+test_empty_response$(EXEEXT): $(test_empty_response_OBJECTS) $(test_empty_response_DEPENDENCIES) $(EXTRA_test_empty_response_DEPENDENCIES) 
+	@rm -f test_empty_response$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_empty_response_OBJECTS) $(test_empty_response_LDADD) $(LIBS)
+
+test_https_get$(EXEEXT): $(test_https_get_OBJECTS) $(test_https_get_DEPENDENCIES) $(EXTRA_test_https_get_DEPENDENCIES) 
+	@rm -f test_https_get$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_https_get_OBJECTS) $(test_https_get_LDADD) $(LIBS)
+
+test_https_get_parallel$(EXEEXT): $(test_https_get_parallel_OBJECTS) $(test_https_get_parallel_DEPENDENCIES) $(EXTRA_test_https_get_parallel_DEPENDENCIES) 
+	@rm -f test_https_get_parallel$(EXEEXT)
+	$(AM_V_CCLD)$(test_https_get_parallel_LINK) $(test_https_get_parallel_OBJECTS) $(test_https_get_parallel_LDADD) $(LIBS)
+
+test_https_get_parallel_threads$(EXEEXT): $(test_https_get_parallel_threads_OBJECTS) $(test_https_get_parallel_threads_DEPENDENCIES) $(EXTRA_test_https_get_parallel_threads_DEPENDENCIES) 
+	@rm -f test_https_get_parallel_threads$(EXEEXT)
+	$(AM_V_CCLD)$(test_https_get_parallel_threads_LINK) $(test_https_get_parallel_threads_OBJECTS) $(test_https_get_parallel_threads_LDADD) $(LIBS)
+
+test_https_get_select$(EXEEXT): $(test_https_get_select_OBJECTS) $(test_https_get_select_DEPENDENCIES) $(EXTRA_test_https_get_select_DEPENDENCIES) 
+	@rm -f test_https_get_select$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_https_get_select_OBJECTS) $(test_https_get_select_LDADD) $(LIBS)
+
+test_https_multi_daemon$(EXEEXT): $(test_https_multi_daemon_OBJECTS) $(test_https_multi_daemon_DEPENDENCIES) $(EXTRA_test_https_multi_daemon_DEPENDENCIES) 
+	@rm -f test_https_multi_daemon$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_https_multi_daemon_OBJECTS) $(test_https_multi_daemon_LDADD) $(LIBS)
+
+test_https_session_info$(EXEEXT): $(test_https_session_info_OBJECTS) $(test_https_session_info_DEPENDENCIES) $(EXTRA_test_https_session_info_DEPENDENCIES) 
+	@rm -f test_https_session_info$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_https_session_info_OBJECTS) $(test_https_session_info_LDADD) $(LIBS)
+
+test_https_sni$(EXEEXT): $(test_https_sni_OBJECTS) $(test_https_sni_DEPENDENCIES) $(EXTRA_test_https_sni_DEPENDENCIES) 
+	@rm -f test_https_sni$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_https_sni_OBJECTS) $(test_https_sni_LDADD) $(LIBS)
+
+test_https_time_out$(EXEEXT): $(test_https_time_out_OBJECTS) $(test_https_time_out_DEPENDENCIES) $(EXTRA_test_https_time_out_DEPENDENCIES) 
+	@rm -f test_https_time_out$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_https_time_out_OBJECTS) $(test_https_time_out_LDADD) $(LIBS)
+
+test_tls_authentication$(EXEEXT): $(test_tls_authentication_OBJECTS) $(test_tls_authentication_DEPENDENCIES) $(EXTRA_test_tls_authentication_DEPENDENCIES) 
+	@rm -f test_tls_authentication$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_tls_authentication_OBJECTS) $(test_tls_authentication_LDADD) $(LIBS)
+
+test_tls_options$(EXEEXT): $(test_tls_options_OBJECTS) $(test_tls_options_DEPENDENCIES) $(EXTRA_test_tls_options_DEPENDENCIES) 
+	@rm -f test_tls_options$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(test_tls_options_OBJECTS) $(test_tls_options_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_empty_response.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_https_get.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_https_get_parallel-test_https_get_parallel.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_https_get_parallel-tls_test_common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_https_get_parallel_threads-test_https_get_parallel_threads.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_https_get_parallel_threads-tls_test_common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_https_get_select.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_https_multi_daemon.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_https_session_info.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_https_sni-test_https_sni.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_https_sni-tls_test_common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_https_time_out.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_tls_authentication.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_tls_options.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tls_test_common.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+test_https_get_parallel-test_https_get_parallel.o: test_https_get_parallel.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_CFLAGS) $(CFLAGS) -MT test_https_get_parallel-test_https_get_parallel.o -MD -MP -MF $(DEPDIR)/test_https_get_parallel-test_https_get_parallel.Tpo -c -o test_https_get_parallel-test_https_get_parallel.o `test -f 'test_https_get_parallel.c' || echo '$(srcdir)/'`test_https_get_parallel.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_get_parallel-test_https_get_parallel.Tpo $(DEPDIR)/test_https_get_parallel-test_https_get_parallel.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test_https_get_parallel.c' object='test_https_get_parallel-test_https_get_parallel.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_CFLAGS) $(CFLAGS) -c -o test_https_get_parallel-test_https_get_parallel.o `test -f 'test_https_get_parallel.c' || echo '$(srcdir)/'`test_https_get_parallel.c
+
+test_https_get_parallel-test_https_get_parallel.obj: test_https_get_parallel.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_CFLAGS) $(CFLAGS) -MT test_https_get_parallel-test_https_get_parallel.obj -MD -MP -MF $(DEPDIR)/test_https_get_parallel-test_https_get_parallel.Tpo -c -o test_https_get_parallel-test_https_get_parallel.obj `if test -f 'test_https_get_parallel.c'; then $(CYGPATH_W) 'test_https_get_parallel.c'; else $(CYGPATH_W) '$(srcdir)/test_https_get_parallel.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_get_parallel-test_https_get_parallel.Tpo $(DEPDIR)/test_https_get_parallel-test_https_get_parallel.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test_https_get_parallel.c' object='test_https_get_parallel-test_https_get_parallel.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_CFLAGS) $(CFLAGS) -c -o test_https_get_parallel-test_https_get_parallel.obj `if test -f 'test_https_get_parallel.c'; then $(CYGPATH_W) 'test_https_get_parallel.c'; else $(CYGPATH_W) '$(srcdir)/test_https_get_parallel.c'; fi`
+
+test_https_get_parallel-tls_test_common.o: tls_test_common.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_CFLAGS) $(CFLAGS) -MT test_https_get_parallel-tls_test_common.o -MD -MP -MF $(DEPDIR)/test_https_get_parallel-tls_test_common.Tpo -c -o test_https_get_parallel-tls_test_common.o `test -f 'tls_test_common.c' || echo '$(srcdir)/'`tls_test_common.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_get_parallel-tls_test_common.Tpo $(DEPDIR)/test_https_get_parallel-tls_test_common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='tls_test_common.c' object='test_https_get_parallel-tls_test_common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_CFLAGS) $(CFLAGS) -c -o test_https_get_parallel-tls_test_common.o `test -f 'tls_test_common.c' || echo '$(srcdir)/'`tls_test_common.c
+
+test_https_get_parallel-tls_test_common.obj: tls_test_common.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_CFLAGS) $(CFLAGS) -MT test_https_get_parallel-tls_test_common.obj -MD -MP -MF $(DEPDIR)/test_https_get_parallel-tls_test_common.Tpo -c -o test_https_get_parallel-tls_test_common.obj `if test -f 'tls_test_common.c'; then $(CYGPATH_W) 'tls_test_common.c'; else $(CYGPATH_W) '$(srcdir)/tls_test_common.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_get_parallel-tls_test_common.Tpo $(DEPDIR)/test_https_get_parallel-tls_test_common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='tls_test_common.c' object='test_https_get_parallel-tls_test_common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_CFLAGS) $(CFLAGS) -c -o test_https_get_parallel-tls_test_common.obj `if test -f 'tls_test_common.c'; then $(CYGPATH_W) 'tls_test_common.c'; else $(CYGPATH_W) '$(srcdir)/tls_test_common.c'; fi`
+
+test_https_get_parallel_threads-test_https_get_parallel_threads.o: test_https_get_parallel_threads.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_threads_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_threads_CFLAGS) $(CFLAGS) -MT test_https_get_parallel_threads-test_https_get_parallel_threads.o -MD -MP -MF $(DEPDIR)/test_https_get_parallel_threads-test_https_get_parallel_threads.Tpo -c -o test_https_get_parallel_threads-test_https_get_parallel_threads.o `test -f 'test_https_get_parallel_threads.c' || echo '$(srcdir)/'`test_https_get_parallel_threads.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_get_parallel_threads-test_https_get_parallel_threads.Tpo $(DEPDIR)/test_https_get_parallel_threads-test_https_get_parallel_threads.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test_https_get_parallel_threads.c' object='test_https_get_parallel_threads-test_https_get_parallel_threads.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_threads_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_threads_CFLAGS) $(CFLAGS) -c -o test_https_get_parallel_threads-test_https_get_parallel_threads.o `test -f 'test_https_get_parallel_threads.c' || echo '$(srcdir)/'`test_https_get_parallel_threads.c
+
+test_https_get_parallel_threads-test_https_get_parallel_threads.obj: test_https_get_parallel_threads.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_threads_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_threads_CFLAGS) $(CFLAGS) -MT test_https_get_parallel_threads-test_https_get_parallel_threads.obj -MD -MP -MF $(DEPDIR)/test_https_get_parallel_threads-test_https_get_parallel_threads.Tpo -c -o test_https_get_parallel_threads-test_https_get_parallel_threads.obj `if test -f 'test_https_get_parallel_threads.c'; then $(CYGPATH_W) 'test_https_get_parallel_threads.c'; else $(CYGPATH_W) '$(srcdir)/test_https_get_parallel_threads.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_get_parallel_threads-test_https_get_parallel_threads.Tpo $(DEPDIR)/test_https_get_parallel_threads-test_https_get_parallel_threads.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test_https_get_parallel_threads.c' object='test_https_get_parallel_threads-test_https_get_parallel_threads.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_threads_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_threads_CFLAGS) $(CFLAGS) -c -o test_https_get_parallel_threads-test_https_get_parallel_threads.obj `if test -f 'test_https_get_parallel_threads.c'; then $(CYGPATH_W) 'test_https_get_parallel_threads.c'; else $(CYGPATH_W) '$(srcdir)/test_https_get_parallel_threads.c'; fi`
+
+test_https_get_parallel_threads-tls_test_common.o: tls_test_common.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_threads_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_threads_CFLAGS) $(CFLAGS) -MT test_https_get_parallel_threads-tls_test_common.o -MD -MP -MF $(DEPDIR)/test_https_get_parallel_threads-tls_test_common.Tpo -c -o test_https_get_parallel_threads-tls_test_common.o `test -f 'tls_test_common.c' || echo '$(srcdir)/'`tls_test_common.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_get_parallel_threads-tls_test_common.Tpo $(DEPDIR)/test_https_get_parallel_threads-tls_test_common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='tls_test_common.c' object='test_https_get_parallel_threads-tls_test_common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_threads_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_threads_CFLAGS) $(CFLAGS) -c -o test_https_get_parallel_threads-tls_test_common.o `test -f 'tls_test_common.c' || echo '$(srcdir)/'`tls_test_common.c
+
+test_https_get_parallel_threads-tls_test_common.obj: tls_test_common.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_threads_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_threads_CFLAGS) $(CFLAGS) -MT test_https_get_parallel_threads-tls_test_common.obj -MD -MP -MF $(DEPDIR)/test_https_get_parallel_threads-tls_test_common.Tpo -c -o test_https_get_parallel_threads-tls_test_common.obj `if test -f 'tls_test_common.c'; then $(CYGPATH_W) 'tls_test_common.c'; else $(CYGPATH_W) '$(srcdir)/tls_test_common.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_get_parallel_threads-tls_test_common.Tpo $(DEPDIR)/test_https_get_parallel_threads-tls_test_common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='tls_test_common.c' object='test_https_get_parallel_threads-tls_test_common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_get_parallel_threads_CPPFLAGS) $(CPPFLAGS) $(test_https_get_parallel_threads_CFLAGS) $(CFLAGS) -c -o test_https_get_parallel_threads-tls_test_common.obj `if test -f 'tls_test_common.c'; then $(CYGPATH_W) 'tls_test_common.c'; else $(CYGPATH_W) '$(srcdir)/tls_test_common.c'; fi`
+
+test_https_sni-test_https_sni.o: test_https_sni.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_sni_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_https_sni-test_https_sni.o -MD -MP -MF $(DEPDIR)/test_https_sni-test_https_sni.Tpo -c -o test_https_sni-test_https_sni.o `test -f 'test_https_sni.c' || echo '$(srcdir)/'`test_https_sni.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_sni-test_https_sni.Tpo $(DEPDIR)/test_https_sni-test_https_sni.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test_https_sni.c' object='test_https_sni-test_https_sni.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_sni_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_https_sni-test_https_sni.o `test -f 'test_https_sni.c' || echo '$(srcdir)/'`test_https_sni.c
+
+test_https_sni-test_https_sni.obj: test_https_sni.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_sni_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_https_sni-test_https_sni.obj -MD -MP -MF $(DEPDIR)/test_https_sni-test_https_sni.Tpo -c -o test_https_sni-test_https_sni.obj `if test -f 'test_https_sni.c'; then $(CYGPATH_W) 'test_https_sni.c'; else $(CYGPATH_W) '$(srcdir)/test_https_sni.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_sni-test_https_sni.Tpo $(DEPDIR)/test_https_sni-test_https_sni.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='test_https_sni.c' object='test_https_sni-test_https_sni.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_sni_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_https_sni-test_https_sni.obj `if test -f 'test_https_sni.c'; then $(CYGPATH_W) 'test_https_sni.c'; else $(CYGPATH_W) '$(srcdir)/test_https_sni.c'; fi`
+
+test_https_sni-tls_test_common.o: tls_test_common.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_sni_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_https_sni-tls_test_common.o -MD -MP -MF $(DEPDIR)/test_https_sni-tls_test_common.Tpo -c -o test_https_sni-tls_test_common.o `test -f 'tls_test_common.c' || echo '$(srcdir)/'`tls_test_common.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_sni-tls_test_common.Tpo $(DEPDIR)/test_https_sni-tls_test_common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='tls_test_common.c' object='test_https_sni-tls_test_common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_sni_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_https_sni-tls_test_common.o `test -f 'tls_test_common.c' || echo '$(srcdir)/'`tls_test_common.c
+
+test_https_sni-tls_test_common.obj: tls_test_common.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_sni_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_https_sni-tls_test_common.obj -MD -MP -MF $(DEPDIR)/test_https_sni-tls_test_common.Tpo -c -o test_https_sni-tls_test_common.obj `if test -f 'tls_test_common.c'; then $(CYGPATH_W) 'tls_test_common.c'; else $(CYGPATH_W) '$(srcdir)/tls_test_common.c'; fi`
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/test_https_sni-tls_test_common.Tpo $(DEPDIR)/test_https_sni-tls_test_common.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='tls_test_common.c' object='test_https_sni-tls_test_common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(test_https_sni_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_https_sni-tls_test_common.obj `if test -f 'tls_test_common.c'; then $(CYGPATH_W) 'tls_test_common.c'; else $(CYGPATH_W) '$(srcdir)/tls_test_common.c'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all $(check_PROGRAMS)
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+test_tls_options.log: test_tls_options$(EXEEXT)
+	@p='test_tls_options$(EXEEXT)'; \
+	b='test_tls_options'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_https_multi_daemon.log: test_https_multi_daemon$(EXEEXT)
+	@p='test_https_multi_daemon$(EXEEXT)'; \
+	b='test_https_multi_daemon'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_https_get.log: test_https_get$(EXEEXT)
+	@p='test_https_get$(EXEEXT)'; \
+	b='test_https_get'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_https_sni.log: test_https_sni$(EXEEXT)
+	@p='test_https_sni$(EXEEXT)'; \
+	b='test_https_sni'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_https_get_select.log: test_https_get_select$(EXEEXT)
+	@p='test_https_get_select$(EXEEXT)'; \
+	b='test_https_get_select'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_https_get_parallel.log: test_https_get_parallel$(EXEEXT)
+	@p='test_https_get_parallel$(EXEEXT)'; \
+	b='test_https_get_parallel'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_https_get_parallel_threads.log: test_https_get_parallel_threads$(EXEEXT)
+	@p='test_https_get_parallel_threads$(EXEEXT)'; \
+	b='test_https_get_parallel_threads'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_https_session_info.log: test_https_session_info$(EXEEXT)
+	@p='test_https_session_info$(EXEEXT)'; \
+	b='test_https_session_info'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_https_time_out.log: test_https_time_out$(EXEEXT)
+	@p='test_https_time_out$(EXEEXT)'; \
+	b='test_https_time_out'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_tls_authentication.log: test_tls_authentication$(EXEEXT)
+	@p='test_tls_authentication$(EXEEXT)'; \
+	b='test_tls_authentication'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+test_empty_response.log: test_empty_response$(EXEEXT)
+	@p='test_empty_response$(EXEEXT)'; \
+	b='test_empty_response'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@	@p='$<'; \
+@am__EXEEXT_TRUE@	$(am__set_b); \
+@am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+	check-TESTS check-am clean clean-checkPROGRAMS clean-generic \
+	clean-libtool cscopelist-am ctags ctags-am distclean \
+	distclean-compile distclean-generic distclean-libtool \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \
+	uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/testcurl/https/cert.pem b/src/testcurl/https/cert.pem
new file mode 100644
index 0000000..2c766df
--- /dev/null
+++ b/src/testcurl/https/cert.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICpjCCAZCgAwIBAgIESEPtjjALBgkqhkiG9w0BAQUwADAeFw0wODA2MDIxMjU0
+MzhaFw0wOTA2MDIxMjU0NDZaMAAwggEfMAsGCSqGSIb3DQEBAQOCAQ4AMIIBCQKC
+AQC03TyUvK5HmUAirRp067taIEO4bibh5nqolUoUdo/LeblMQV+qnrv/RNAMTx5X
+fNLZ45/kbM9geF8qY0vsPyQvP4jumzK0LOJYuIwmHaUm9vbXnYieILiwCuTgjaud
+3VkZDoQ9fteIo+6we9UTpVqZpxpbLulBMh/VsvX0cPJ1VFC7rT59o9hAUlFf9jX/
+GmKdYI79MtgVx0OPBjmmSD6kicBBfmfgkO7bIGwlRtsIyMznxbHu6VuoX/eVxrTv
+rmCwgEXLWRZ6ru8MQl5YfqeGXXRVwMeXU961KefbuvmEPccgCxm8FZ1C1cnDHFXh
+siSgAzMBjC/b6KVhNQ4KnUdZAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0O
+BBYEFJcUvpjvE5fF/yzUshkWDpdYiQh/MAsGCSqGSIb3DQEBBQOCAQEARP7eKSB2
+RNd6XjEjK0SrxtoTnxS3nw9sfcS7/qD1+XHdObtDFqGNSjGYFB3Gpx8fpQhCXdoN
+8QUs3/5ZVa5yjZMQewWBgz8kNbnbH40F2y81MHITxxCe1Y+qqHWwVaYLsiOTqj2/
+0S3QjEJ9tvklmg7JX09HC4m5QRYfWBeQLD1u8ZjA1Sf1xJriomFVyRLI2VPO2bNe
+JDMXWuP+8kMC7gEvUnJ7A92Y2yrhu3QI3bjPk8uSpHea19Q77tul1UVBJ5g+zpH3
+OsF5p0MyaVf09GTzcLds5nE/osTdXGUyHJapWReVmPm3Zn6gqYlnzD99z+DPIgIV
+RhZvQx74NQnS6g==
+-----END CERTIFICATE-----
diff --git a/src/testcurl/https/host1.crt b/src/testcurl/https/host1.crt
new file mode 100644
index 0000000..d9b8b99
--- /dev/null
+++ b/src/testcurl/https/host1.crt
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICWTCCAcICCQDc4McLp7j56DANBgkqhkiG9w0BAQUFADBwMQswCQYDVQQGEwJa
+WjETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMQ4wDAYDVQQDDAVob3N0MTEZMBcGCSqGSIb3DQEJARYKdGVzdEBo
+b3N0MTAgFw0xMzExMTcxNTE2MzdaGA8yMTEzMTAyNDE1MTYzN1owcDELMAkGA1UE
+BhMCWloxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp
+ZGdpdHMgUHR5IEx0ZDEOMAwGA1UEAwwFaG9zdDExGTAXBgkqhkiG9w0BCQEWCnRl
+c3RAaG9zdDEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKxYiRUzfQnekQn3
+6e+hP/mt/JEkiFzX5TV+E19ue2v4tc7lf+SoLEk2dVt5tGQkHjIGeFFNwCLrgXoi
+h3KfP4R1IYe7NFbM+lFVwPceF3inJ75dZD80BxaXQANeh0yC/DhaVJUFNaof2S4+
+7xd8zTL6M11gME+XmR8uaDvW7EBtAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAf62m
+Nstj9p9u8T5A5fRnJWfoglH/zfm7IHzht0Wi047O3NFZJ0pOPqV97HuErUA5oBGg
+qswnyRGyGMcvL08Bki7Q6NkY7K0ON3lq+ofTkIAHlOKMF+Y/otbjuIDHBfo63tmE
+uOcr8XDQGu9R0cfh+qLgicJQd/8cFBhxsL0ls6I=
+-----END CERTIFICATE-----
diff --git a/src/testcurl/https/host1.key b/src/testcurl/https/host1.key
new file mode 100644
index 0000000..f549a4d
--- /dev/null
+++ b/src/testcurl/https/host1.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQCsWIkVM30J3pEJ9+nvoT/5rfyRJIhc1+U1fhNfbntr+LXO5X/k
+qCxJNnVbebRkJB4yBnhRTcAi64F6Iodynz+EdSGHuzRWzPpRVcD3Hhd4pye+XWQ/
+NAcWl0ADXodMgvw4WlSVBTWqH9kuPu8XfM0y+jNdYDBPl5kfLmg71uxAbQIDAQAB
+AoGBAJvq9QmjLSnymtCj4pYSEai2iNpebKdiAlEkoC4j67DArupgohWhN398ryt0
+rYgzTMYBKHSVnI969AYkmtlNzM1yNckRQb/G/tWrkl9re28y2nbAExtHbvLoTk2C
+a/EEl1Op+JZNzLoSje7IQMVZoArD3d4aUbfux4XzlO2eRNmZAkEA2pV49QgcOTOJ
+PrR5cgekonNdeMtkbZm9dhxgDk9IsYkC0iOxjn/IbeCQN3wuTQ5/yLoiiQ/CQ8w5
+JndF/XpICwJBAMnY37BSRb+XKZeJWP0yjqyFJwzHXkh6IsoSF2OOXSixdiMpthLh
+IPzvo6Qxsnha4VvwuDxljHzQFPgMT//CTGcCQQDMs9S+LKU50JDEX4Goj43X8RBl
+cp0Poz3yYap3XDqowLYalADRgcvzUq3cuHgoA98Z3W9ASrjUg2o2ItcyBhV3AkAK
+bCBgwl7Hnc6P/I+Tw2CKl/WEO2cq5uOU+4opodg9maw39JdqMiW56cXRXJ+Sh17L
+mIpq0/OFHll21WvsEORRAkAnDDn/vmW25PSxPVY7tKKJCCkmtBeLQpySfpDgBF+O
+QvvokKs2COivc50rmOYNvD1WSsAOspdaSoZUgFw5ikti
+-----END RSA PRIVATE KEY-----
diff --git a/src/testcurl/https/host2.crt b/src/testcurl/https/host2.crt
new file mode 100644
index 0000000..ac28b0e
--- /dev/null
+++ b/src/testcurl/https/host2.crt
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICWTCCAcICCQCJ9nhDYTUBKjANBgkqhkiG9w0BAQUFADBwMQswCQYDVQQGEwJa
+WjETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMQ4wDAYDVQQDDAVob3N0MjEZMBcGCSqGSIb3DQEJARYKdGVzdEBo
+b3N0MjAgFw0xMzExMTcxNTE2NDNaGA8yMTEzMTAyNDE1MTY0M1owcDELMAkGA1UE
+BhMCWloxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp
+ZGdpdHMgUHR5IEx0ZDEOMAwGA1UEAwwFaG9zdDIxGTAXBgkqhkiG9w0BCQEWCnRl
+c3RAaG9zdDIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALVK8QKMvU96iNL2
+66PKm6xXw9NPHDn+o1TLF1CQRxXMrBYUrObk0961+3n3Z3BXOFHKfSV4E55CpVyz
+D1Wcadlt3B9z3ke3HOi0lEa1xNJTMQK/QT3Fx/NURmNg5s9HAsqY4ocb9KHaF5Ex
+0TgC0L0aRP0cK1x2TgPEHBNcgGl9AgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAEXOi
+9rSmVrTN5olIdowctr1vWbGwRCjCnAFXDsqakcDASNthr15LB5kr/mrA3olJjbZh
+o+JDvWMY6FN8r1QXW0RL9/obbHxtJpwvAmYVMY9jrR8Rpo38p4RfXlN85g3q9PVx
+5IGLaOqLf4hSnKArFL/fzXwxX9b5HBCKlXfiuqM=
+-----END CERTIFICATE-----
diff --git a/src/testcurl/https/host2.key b/src/testcurl/https/host2.key
new file mode 100644
index 0000000..4bbd617
--- /dev/null
+++ b/src/testcurl/https/host2.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICWwIBAAKBgQC1SvECjL1PeojS9uujypusV8PTTxw5/qNUyxdQkEcVzKwWFKzm
+5NPetft592dwVzhRyn0leBOeQqVcsw9VnGnZbdwfc95HtxzotJRGtcTSUzECv0E9
+xcfzVEZjYObPRwLKmOKHG/Sh2heRMdE4AtC9GkT9HCtcdk4DxBwTXIBpfQIDAQAB
+AoGAR5Do6TfDt69IefdNeCAQKg2PWUg+fUpfEacGciAyX5GnUSQiSReF58HxHumi
+ZL+ZlPgZRQRMwknO23Q4FnSjd66A3E9iHLqkWxRFJWME6E7zgtBrIjctnNu9uYM9
+cw4R6qmXOL7C5sK00KXF2ep8+s+JjrZz61o85QnGGRYA94ECQQDbG6f1B8NKY9T1
+1GDR/++rJbdTVQlZQcKSXMumpU6V3mEV0O9GkYaZzoYvWa3kx6c0np4karrm3QWa
+u5E0q1YdAkEA09FPcmzVvIR0+sMWca8QJ/tJUxD6qYo8vLOpO4wt4iTPhGBEU+Q5
+cgXmde3/plVsp0vYxK/NG5XZkoC1fbuC4QJATRGxRlLwsl3jLoUBeVxY5Q5jKYCj
+xS2ITwss5vUGa1jJNW9EesH9YmRudoFI1UwU2EFixtRz4Xik3ARV0vzhUQJAfabT
+50ASxqMYtczW2peMEPurMqCG4d4ES7iUMqPkcBuAErn8rntbbH19igWmOyi/rLp8
+m6jiFnQdPiAmCbEbYQJAFAKiQl2ZOe3gkSh8MaQilD8Ppog6rod4SQiSmRNsDWPi
+IxqXneaGDWhzynC9xr4SwuJ9D5VxW1phNyiveDuYXw==
+-----END RSA PRIVATE KEY-----
diff --git a/src/testcurl/https/key.pem b/src/testcurl/https/key.pem
new file mode 100644
index 0000000..a5848ee
--- /dev/null
+++ b/src/testcurl/https/key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAtN08lLyuR5lAIq0adOu7WiBDuG4m4eZ6qJVKFHaPy3m5TEFf
+qp67/0TQDE8eV3zS2eOf5GzPYHhfKmNL7D8kLz+I7psytCziWLiMJh2lJvb2152I
+niC4sArk4I2rnd1ZGQ6EPX7XiKPusHvVE6VamacaWy7pQTIf1bL19HDydVRQu60+
+faPYQFJRX/Y1/xpinWCO/TLYFcdDjwY5pkg+pInAQX5n4JDu2yBsJUbbCMjM58Wx
+7ulbqF/3lca0765gsIBFy1kWeq7vDEJeWH6nhl10VcDHl1PetSnn27r5hD3HIAsZ
+vBWdQtXJwxxV4bIkoAMzAYwv2+ilYTUOCp1HWQIDAQABAoIBAArOQv3R7gmqDspj
+lDaTFOz0C4e70QfjGMX0sWnakYnDGn6DU19iv3GnX1S072ejtgc9kcJ4e8VUO79R
+EmqpdRR7k8dJr3RTUCyjzf/C+qiCzcmhCFYGN3KRHA6MeEnkvRuBogX4i5EG1k5l
+/5t+YBTZBnqXKWlzQLKoUAiMLPg0eRWh+6q7H4N7kdWWBmTpako7TEqpIwuEnPGx
+u3EPuTR+LN6lF55WBePbCHccUHUQaXuav18NuDkcJmCiMArK9SKb+h0RqLD6oMI/
+dKD6n8cZXeMBkK+C8U/K0sN2hFHACsu30b9XfdnljgP9v+BP8GhnB0nCB6tNBCPo
+32srOwECgYEAxWh3iBT4lWqL6bZavVbnhmvtif4nHv2t2/hOs/CAq8iLAw0oWGZc
++JEZTUDMvFRlulr0kcaWra+4fN3OmJnjeuFXZq52lfMgXBIKBmoSaZpIh2aDY1Rd
+RbEse7nQl9hTEPmYspiXLGtnAXW7HuWqVfFFP3ya8rUS3t4d07Hig8ECgYEA6ou6
+OHiBRTbtDqLIv8NghARc/AqwNWgEc9PelCPe5bdCOLBEyFjqKiT2MttnSSUc2Zob
+XhYkHC6zN1Mlq30N0e3Q61YK9LxMdU1vsluXxNq2rfK1Scb1oOlOOtlbV3zA3VRF
+hV3t1nOA9tFmUrwZi0CUMWJE/zbPAyhwWotKyZkCgYEAh0kFicPdbABdrCglXVae
+SnfSjVwYkVuGd5Ze0WADvjYsVkYBHTvhgRNnRJMg+/vWz3Sf4Ps4rgUbqK8Vc20b
+AU5G6H6tlCvPRGm0ZxrwTWDHTcuKRVs+pJE8C/qWoklE/AAhjluWVoGwUMbPGuiH
+6Gf1bgHF6oj/Sq7rv/VLZ8ECgYBeq7ml05YyLuJutuwa4yzQ/MXfghzv4aVyb0F3
+QCdXR6o2IYgR6jnSewrZKlA9aPqFJrwHNR6sNXlnSmt5Fcf/RWO/qgJQGLUv3+rG
+7kuLTNDR05azSdiZc7J89ID3Bkb+z2YkV+6JUiPq/Ei1+nDBEXb/m+/HqALU/nyj
+P3gXeQKBgBusb8Rbd+KgxSA0hwY6aoRTPRt8LNvXdsB9vRcKKHUFQvxUWiUSS+L9
+/Qu1sJbrUquKOHqksV5wCnWnAKyJNJlhHuBToqQTgKXjuNmVdYSe631saiI7PHyC
+eRJ6DxULPxABytJrYCRrNqmXi5TCiqR2mtfalEMOPxz8rUU8dYyx
+-----END RSA PRIVATE KEY-----
diff --git a/src/testcurl/https/test_empty_response.c b/src/testcurl/https/test_empty_response.c
new file mode 100644
index 0000000..f9f8001
--- /dev/null
+++ b/src/testcurl/https/test_empty_response.c
@@ -0,0 +1,201 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2013 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING.  If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file test_empty_response.c
+ * @brief  Testcase for libmicrohttpd HTTPS GET operations with emtpy reply
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "microhttpd.h"
+#include <limits.h>
+#include <sys/stat.h>
+#include <curl/curl.h>
+#include <gcrypt.h>
+#include "tls_test_common.h"
+
+extern const char srv_key_pem[];
+extern const char srv_self_signed_cert_pem[];
+extern const char srv_signed_cert_pem[];
+extern const char srv_signed_key_pem[];
+
+static int oneone;
+
+static int
+ahc_echo (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;
+
+  response = MHD_create_response_from_buffer (0, NULL,
+					      MHD_RESPMEM_PERSISTENT);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  return ret;
+}
+
+
+static int
+testInternalSelectGet ()
+{
+  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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL | MHD_USE_SELECT_INTERNALLY,
+                        1082, NULL, NULL, &ahc_echo, "GET", 
+                        MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
+                        MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+
+  char *aes256_sha = "AES256-SHA";
+  if (curl_uses_nss_ssl() == 0)
+    {
+      aes256_sha = "rsa_aes_256_sha";
+    }
+
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "https://127.0.0.1:1082/hello_world");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  /* TLS options */
+  curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
+  curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, aes256_sha);
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  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, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      if (mret != CURLM_OK)
+        {
+          curl_multi_remove_handle (multi, c);
+          curl_multi_cleanup (multi);
+          curl_easy_cleanup (c);
+          MHD_stop_daemon (d);
+          return 2048;
+        }
+      tv.tv_sec = 0;
+      tv.tv_usec = 1000;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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;
+            }
+        }
+    }
+  if (multi != NULL)
+    {
+      curl_multi_remove_handle (multi, c);
+      curl_easy_cleanup (c);
+      curl_multi_cleanup (multi);
+    }
+  MHD_stop_daemon (d);
+  if (cbc.pos != 0)
+    return 8192;
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  if (0 != curl_global_init (CURL_GLOBAL_ALL))
+    {
+      fprintf (stderr, "Error: %s\n", strerror (errno));
+      return -1;
+    }
+  if (0 != (errorCount = testInternalSelectGet ()))
+    fprintf (stderr, "Fail: %d\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;
+}
diff --git a/src/testcurl/https/test_https_get.c b/src/testcurl/https/test_https_get.c
new file mode 100644
index 0000000..f7957c3
--- /dev/null
+++ b/src/testcurl/https/test_https_get.c
@@ -0,0 +1,130 @@
+/*
+  This file is part of libmicrohttpd
+  Copyright (C) 2007 Christian Grothoff
+
+  libmicrohttpd is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 3, or (at your
+  option) any later version.
+
+  libmicrohttpd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with libmicrohttpd; see the file COPYING.  If not, write to the
+  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+  Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_https_get.c
+ * @brief  Testcase for libmicrohttpd HTTPS GET operations
+ * @author Sagie Amir
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include <limits.h>
+#include <sys/stat.h>
+#include <curl/curl.h>
+#include <gcrypt.h>
+#include "tls_test_common.h"
+
+extern const char srv_key_pem[];
+extern const char srv_self_signed_cert_pem[];
+extern const char srv_signed_cert_pem[];
+extern const char srv_signed_key_pem[];
+
+
+static int
+test_cipher_option (FILE * test_fd,
+		    const char *cipher_suite,
+		    int proto_version)
+{
+
+  int ret;
+  struct MHD_Daemon *d;
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
+                        MHD_USE_DEBUG, 4233,
+                        NULL, NULL, &http_ahc, NULL,
+                        MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
+                        MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
+                        MHD_OPTION_END);
+
+  if (d == NULL)
+    {
+      fprintf (stderr, MHD_E_SERVER_INIT);
+      return -1;
+    }
+
+  ret = test_https_transfer (test_fd, cipher_suite, proto_version);
+
+  MHD_stop_daemon (d);
+  return ret;
+}
+
+
+/* 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;
+
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
+                        MHD_USE_DEBUG, 4233,
+                        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;
+    }
+
+  ret = test_https_transfer (test_fd, cipher_suite, proto_version);
+
+  MHD_stop_daemon (d);
+  return ret;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+  const char *aes256_sha_tlsv1   = "AES256-SHA";
+  const char *des_cbc3_sha_tlsv1 = "DES-CBC3-SHA";
+
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+  if (0 != curl_global_init (CURL_GLOBAL_ALL))
+    {
+      fprintf (stderr, "Error: %s\n", strerror (errno));
+      return -1;
+    }
+
+  if (curl_uses_nss_ssl() == 0)
+    {
+      aes256_sha_tlsv1 = "rsa_aes_256_sha";
+      des_cbc3_sha_tlsv1 = "rsa_aes_128_sha";
+    }
+
+  errorCount +=
+    test_secure_get (NULL, aes256_sha_tlsv1, CURL_SSLVERSION_TLSv1);
+  errorCount +=
+    test_cipher_option (NULL, des_cbc3_sha_tlsv1, CURL_SSLVERSION_TLSv1);
+  print_test_result (errorCount, argv[0]);
+
+  curl_global_cleanup ();
+
+  return errorCount != 0;
+}
diff --git a/src/testcurl/https/test_https_get_parallel.c b/src/testcurl/https/test_https_get_parallel.c
new file mode 100644
index 0000000..166e400
--- /dev/null
+++ b/src/testcurl/https/test_https_get_parallel.c
@@ -0,0 +1,185 @@
+/*
+  This file is part of libmicrohttpd
+  Copyright (C) 2007 Christian Grothoff
+
+  libmicrohttpd is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2, or (at your
+  option) any later version.
+
+  libmicrohttpd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with libmicrohttpd; see the file COPYING.  If not, write to the
+  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+  Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_https_get_parallel.c
+ * @brief  Testcase for libmicrohttpd HTTPS GET operations
+ * @author Sagie Amir
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include <sys/stat.h>
+#include <limits.h>
+#include <curl/curl.h>
+#include <pthread.h>
+#include <gcrypt.h>
+#include "tls_test_common.h"
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 4
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 4
+#endif
+
+extern const char srv_key_pem[];
+extern const char srv_self_signed_cert_pem[];
+
+int curl_check_version (const char *req_version, ...);
+
+
+/**
+ * used when spawning multiple threads executing curl server requests
+ *
+ */
+static void *
+https_transfer_thread_adapter (void *args)
+{
+  static int nonnull;
+  struct https_test_data *cargs = args;
+  int ret;
+
+  /* time spread incomming requests */
+  usleep ((useconds_t) 10.0 * ((double) rand ()) / ((double) RAND_MAX));
+  ret = test_https_transfer (NULL,
+                             cargs->cipher_suite, cargs->proto_version);
+  if (ret == 0)
+    return NULL;
+  return &nonnull;
+}
+
+
+/**
+ * Test non-parallel requests.
+ *
+ * @return: 0 upon all client requests returning '0', -1 otherwise.
+ *
+ * TODO : make client_count a parameter - number of curl client threads to spawn
+ */
+static int
+test_single_client (void *cls, const char *cipher_suite,
+                    int curl_proto_version)
+{
+  void *client_thread_ret;
+  struct https_test_data client_args =
+    { NULL, cipher_suite, curl_proto_version };
+
+  client_thread_ret = https_transfer_thread_adapter (&client_args);
+  if (client_thread_ret != NULL)
+    return -1;
+  return 0;
+}
+
+
+/**
+ * Test parallel request handling.
+ *
+ * @return: 0 upon all client requests returning '0', -1 otherwise.
+ *
+ * TODO : make client_count a parameter - numver of curl client threads to spawn
+ */
+static int
+test_parallel_clients (void * cls, const char *cipher_suite,
+                       int curl_proto_version)
+{
+  int i;
+  int client_count = (CPU_COUNT - 1);
+  void *client_thread_ret;
+  pthread_t client_arr[client_count];
+  struct https_test_data client_args =
+    { NULL, cipher_suite, curl_proto_version };
+
+  for (i = 0; i < client_count; ++i)
+    {
+      if (pthread_create (&client_arr[i], NULL,
+                          &https_transfer_thread_adapter, &client_args) != 0)
+        {
+          fprintf (stderr, "Error: failed to spawn test client threads.\n");
+          return -1;
+        }
+    }
+
+  /* check all client requests fulfilled correctly */
+  for (i = 0; i < client_count; ++i)
+    {
+      if ((pthread_join (client_arr[i], &client_thread_ret) != 0) ||
+          (client_thread_ret != NULL))
+        return -1;
+    }
+
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{  
+  unsigned int errorCount = 0;
+  const char *aes256_sha = "AES256-SHA";
+
+  /* initialize random seed used by curl clients */
+  unsigned int iseed = (unsigned int) time (NULL);
+  srand (iseed);
+  if (0 != curl_global_init (CURL_GLOBAL_ALL))
+    {
+      fprintf (stderr, "Error: %s\n", strerror (errno));
+      return -1;
+    }
+
+  if (curl_uses_nss_ssl() == 0)
+    aes256_sha = "rsa_aes_256_sha";    
+#if EPOLL_SUPPORT
+  errorCount +=
+    test_wrap ("single threaded daemon, single client, epoll", &test_single_client,
+               NULL,
+               MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL | MHD_USE_DEBUG | MHD_USE_EPOLL_LINUX_ONLY,
+               aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
+               srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
+               srv_self_signed_cert_pem, MHD_OPTION_END);
+#endif
+  errorCount +=
+    test_wrap ("single threaded daemon, single client", &test_single_client,
+               NULL,
+               MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL | MHD_USE_DEBUG,
+               aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
+               srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
+               srv_self_signed_cert_pem, MHD_OPTION_END);
+#if EPOLL_SUPPORT
+  errorCount +=
+    test_wrap ("single threaded daemon, parallel clients, epoll",
+               &test_parallel_clients, NULL,
+               MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL | MHD_USE_DEBUG | MHD_USE_EPOLL_LINUX_ONLY,
+               aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
+               srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
+               srv_self_signed_cert_pem, MHD_OPTION_END);
+#endif
+  errorCount +=
+    test_wrap ("single threaded daemon, parallel clients",
+               &test_parallel_clients, NULL,
+               MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL | MHD_USE_DEBUG,
+               aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
+               srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
+               srv_self_signed_cert_pem, MHD_OPTION_END);
+
+  curl_global_cleanup ();
+  return errorCount != 0;
+}
diff --git a/src/testcurl/https/test_https_get_parallel_threads.c b/src/testcurl/https/test_https_get_parallel_threads.c
new file mode 100644
index 0000000..4cb2128
--- /dev/null
+++ b/src/testcurl/https/test_https_get_parallel_threads.c
@@ -0,0 +1,191 @@
+/*
+  This file is part of libmicrohttpd
+  Copyright (C) 2007 Christian Grothoff
+
+  libmicrohttpd is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2, or (at your
+  option) any later version.
+
+  libmicrohttpd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with libmicrohttpd; see the file COPYING.  If not, write to the
+  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+  Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file tls_thread_mode_test.c
+ * @brief  Testcase for libmicrohttpd HTTPS GET operations
+ * @author Sagie Amir
+ * @author Christian Grothoff
+ *
+ * TODO: add test for external select!
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include <sys/stat.h>
+#include <limits.h>
+#include <curl/curl.h>
+#include <pthread.h>
+#include <gcrypt.h>
+#include "tls_test_common.h"
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 4
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 4
+#endif
+
+extern const char srv_key_pem[];
+extern const char srv_self_signed_cert_pem[];
+
+int curl_check_version (const char *req_version, ...);
+
+/**
+ * used when spawning multiple threads executing curl server requests
+ *
+ */
+static void *
+https_transfer_thread_adapter (void *args)
+{
+  static int nonnull;
+  struct https_test_data *cargs = args;
+  int ret;
+
+  /* time spread incomming requests */
+  usleep ((useconds_t) 10.0 * ((double) rand ()) / ((double) RAND_MAX));
+  ret = test_https_transfer (cargs->cls,
+                             cargs->cipher_suite, cargs->proto_version);
+  if (ret == 0)
+    return NULL;
+  return &nonnull;
+}
+
+/**
+ * Test non-parallel requests.
+ *
+ * @return: 0 upon all client requests returning '0', -1 otherwise.
+ *
+ * TODO : make client_count a parameter - numver of curl client threads to spawn
+ */
+static int
+test_single_client (void *cls, const char *cipher_suite,
+                    int curl_proto_version)
+{
+  void *client_thread_ret;
+  struct https_test_data client_args =
+    { NULL, cipher_suite, curl_proto_version };
+
+  client_thread_ret = https_transfer_thread_adapter (&client_args);
+  if (client_thread_ret != NULL)
+    return -1;
+  return 0;
+}
+
+
+/**
+ * Test parallel request handling.
+ *
+ * @return: 0 upon all client requests returning '0', -1 otherwise.
+ *
+ * TODO : make client_count a parameter - numver of curl client threads to spawn
+ */
+static int
+test_parallel_clients (void *cls, const char *cipher_suite,
+                       int curl_proto_version)
+{
+  int i;
+  int client_count = (CPU_COUNT - 1);
+  void *client_thread_ret;
+  pthread_t client_arr[client_count];
+  struct https_test_data client_args =
+    { NULL, cipher_suite, curl_proto_version };
+
+  for (i = 0; i < client_count; ++i)
+    {
+      if (pthread_create (&client_arr[i], NULL,
+                          &https_transfer_thread_adapter, &client_args) != 0)
+        {
+          fprintf (stderr, "Error: failed to spawn test client threads.\n");
+
+          return -1;
+        }
+    }
+
+  /* check all client requests fulfilled correctly */
+  for (i = 0; i < client_count; ++i)
+    {
+      if ((pthread_join (client_arr[i], &client_thread_ret) != 0) ||
+          (client_thread_ret != NULL))
+        return -1;
+    }
+
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+  const char *ssl_version;
+
+  /* initialize random seed used by curl clients */
+  unsigned int iseed = (unsigned int) time (NULL);
+
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+  srand (iseed);
+  ssl_version = curl_version_info (CURLVERSION_NOW)->ssl_version;
+  if (NULL == ssl_version)
+  {
+    fprintf (stderr, "Curl does not support SSL.  Cannot run the test.\n");
+    return 0;
+  }
+  if (0 != strncmp (ssl_version, "GnuTLS", 6))
+  {
+    fprintf (stderr, "This test can be run only with libcurl-gnutls.\n");
+    return 0;
+  }
+  if (0 != curl_global_init (CURL_GLOBAL_ALL))
+    {
+      fprintf (stderr, "Error: %s\n", strerror (errno));
+      return -1;
+    }
+
+  char *aes256_sha = "AES256-SHA";
+  if (curl_uses_nss_ssl() == 0)
+    {
+      aes256_sha = "rsa_aes_256_sha";
+    }
+
+  errorCount +=
+    test_wrap ("multi threaded daemon, single client", &test_single_client,
+               NULL,
+               MHD_USE_SSL | MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION,
+               aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
+               srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
+               srv_self_signed_cert_pem, MHD_OPTION_END);
+
+  errorCount +=
+    test_wrap ("multi threaded daemon, parallel client",
+               &test_parallel_clients, NULL,
+               MHD_USE_SSL | MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION,
+               aes256_sha, CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
+               srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
+               srv_self_signed_cert_pem, MHD_OPTION_END);
+
+  if (errorCount != 0)
+    fprintf (stderr, "Failed test: %s.\n", argv[0]);
+
+  curl_global_cleanup ();
+  return errorCount != 0;
+}
diff --git a/src/testcurl/https/test_https_get_select.c b/src/testcurl/https/test_https_get_select.c
new file mode 100644
index 0000000..9f9ba99
--- /dev/null
+++ b/src/testcurl/https/test_https_get_select.c
@@ -0,0 +1,228 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING.  If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file test_https_get_select.c
+ * @brief  Testcase for libmicrohttpd HTTPS GET operations
+ * @author Sagie Amir
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include <limits.h>
+#include <sys/stat.h>
+#include <curl/curl.h>
+#include <gcrypt.h>
+#include "tls_test_common.h"
+
+extern const char srv_key_pem[];
+extern const char srv_self_signed_cert_pem[];
+extern const char srv_signed_cert_pem[];
+extern const char srv_signed_key_pem[];
+
+static int oneone;
+
+static int
+ahc_echo (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;
+  const char *me = cls;
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  response = MHD_create_response_from_buffer (strlen (url),
+					      (void *) url,
+					      MHD_RESPMEM_MUST_COPY);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+static int
+testExternalGet (int flags)
+{
+  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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+  const char *aes256_sha = "AES256-SHA";
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL | flags,
+                        1082, NULL, NULL, &ahc_echo, "GET", 
+                        MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
+                        MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+
+  if (curl_uses_nss_ssl() == 0)
+    aes256_sha = "rsa_aes_256_sha";   
+
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "https://127.0.0.1:1082/hello_world");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  /* TLS options */
+  curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
+  curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, aes256_sha);
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  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, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      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, &max))
+        {
+          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;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  if (0 != curl_global_init (CURL_GLOBAL_ALL))
+    {
+      fprintf (stderr, "Error: %s\n", strerror (errno));
+      return -1;
+    }
+#if EPOLL_SUPPORT
+  if (0 != (errorCount = testExternalGet (MHD_USE_EPOLL_LINUX_ONLY)))
+    fprintf (stderr, "Fail: %d\n", errorCount);
+#endif
+  if (0 != (errorCount = testExternalGet (0)))
+    fprintf (stderr, "Fail: %d\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;
+}
diff --git a/src/testcurl/https/test_https_multi_daemon.c b/src/testcurl/https/test_https_multi_daemon.c
new file mode 100644
index 0000000..293aff4
--- /dev/null
+++ b/src/testcurl/https/test_https_multi_daemon.c
@@ -0,0 +1,134 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING.  If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file mhds_multi_daemon_test.c
+ * @brief  Testcase for libmicrohttpd multiple HTTPS daemon scenario
+ * @author Sagie Amir
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include <curl/curl.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <gcrypt.h>
+#include "tls_test_common.h"
+
+extern int curl_check_version (const char *req_version, ...);
+extern const char srv_key_pem[];
+extern const char srv_self_signed_cert_pem[];
+
+/*
+ * assert initiating two separate daemons and having one shut down
+ * doesn't affect the other
+ */
+static int
+test_concurent_daemon_pair (void *cls, 
+			    const char *cipher_suite,
+                            int proto_version)
+{
+
+  int ret;
+  struct MHD_Daemon *d1;
+  struct MHD_Daemon *d2;
+
+  d1 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
+                         MHD_USE_DEBUG, DEAMON_TEST_PORT,
+                         NULL, NULL, &http_ahc, NULL,
+                         MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
+                         MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
+                         MHD_OPTION_END);
+
+  if (d1 == NULL)
+    {
+      fprintf (stderr, MHD_E_SERVER_INIT);
+      return -1;
+    }
+
+  d2 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
+                         MHD_USE_DEBUG, DEAMON_TEST_PORT + 1,
+                         NULL, NULL, &http_ahc, NULL,
+                         MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
+                         MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
+                         MHD_OPTION_END);
+
+  if (d2 == NULL)
+    {
+      MHD_stop_daemon (d1);
+      fprintf (stderr, MHD_E_SERVER_INIT);
+      return -1;
+    }
+
+  ret =
+    test_daemon_get (NULL, cipher_suite, proto_version, DEAMON_TEST_PORT, 0);
+  ret +=
+    test_daemon_get (NULL, cipher_suite, proto_version,
+                     DEAMON_TEST_PORT + 1, 0);
+
+  MHD_stop_daemon (d2);
+  ret +=
+    test_daemon_get (NULL, cipher_suite, proto_version, DEAMON_TEST_PORT, 0);
+  MHD_stop_daemon (d1);
+  return ret;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+  FILE *cert;
+
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+  if (0 != curl_global_init (CURL_GLOBAL_ALL))
+    {
+      fprintf (stderr, "Error (code: %u). l:%d f:%s\n", errorCount, __LINE__,
+               __FUNCTION__);
+      return -1;
+    }
+  if ((cert = setup_ca_cert ()) == NULL)
+    {
+      fprintf (stderr, MHD_E_TEST_FILE_CREAT);
+      return -1;
+    }
+
+  const char *aes256_sha = "AES256-SHA";
+  if (curl_uses_nss_ssl() == 0)
+    {
+      aes256_sha = "rsa_aes_256_sha";
+    }
+  
+  errorCount +=
+    test_concurent_daemon_pair (NULL, aes256_sha, CURL_SSLVERSION_TLSv1);
+
+  print_test_result (errorCount, "concurent_daemon_pair");
+
+  curl_global_cleanup ();
+  fclose (cert);
+  if (0 != remove (ca_cert_file_name))
+    fprintf (stderr,
+	     "Failed to remove `%s'\n",
+	     ca_cert_file_name);
+  return errorCount != 0;
+}
diff --git a/src/testcurl/https/test_https_session_info.c b/src/testcurl/https/test_https_session_info.c
new file mode 100644
index 0000000..8dac253
--- /dev/null
+++ b/src/testcurl/https/test_https_session_info.c
@@ -0,0 +1,186 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING.  If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file mhds_session_info_test.c
+ * @brief  Testcase for libmicrohttpd HTTPS connection querying operations
+ * @author Sagie Amir
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include <curl/curl.h>
+#include <gcrypt.h>
+#include "tls_test_common.h"
+
+extern int curl_check_version (const char *req_version, ...);
+extern const char srv_key_pem[];
+extern const char srv_self_signed_cert_pem[];
+
+struct MHD_Daemon *d;
+
+/*
+ * HTTP access handler call back
+ * used to query negotiated security parameters
+ */
+static int
+query_session_ahc (void *cls, struct MHD_Connection *connection,
+                   const char *url, const char *method,
+                   const char *upload_data, const char *version,
+                   size_t *upload_data_size, void **ptr)
+{
+  struct MHD_Response *response;
+  int ret;
+
+  if (NULL == *ptr)
+    {
+      *ptr = &query_session_ahc;
+      return MHD_YES;
+    }
+
+  if (GNUTLS_TLS1_1 !=
+      (ret = MHD_get_connection_info
+       (connection,
+	MHD_CONNECTION_INFO_PROTOCOL)->protocol))
+    {
+      if (GNUTLS_TLS1_2 == ret)
+      {
+        /* as usual, TLS implementations sometimes don't
+           quite do what was asked, just mildly complain... */
+        fprintf (stderr,
+                 "Warning: requested TLS 1.1, got TLS 1.2\n");
+      }
+      else
+      {
+        /* really different version... */
+        fprintf (stderr,
+                 "Error: requested protocol mismatch (wanted %d, got %d)\n",
+                 GNUTLS_TLS1_1,
+                 ret);
+        return -1;
+      }
+    }
+
+  response = MHD_create_response_from_buffer (strlen (EMPTY_PAGE),
+					      (void *) EMPTY_PAGE,
+					      MHD_RESPMEM_PERSISTENT);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  return ret;
+}
+
+
+/**
+ * negotiate a secure connection with server & query negotiated security parameters
+ */
+static int
+test_query_session ()
+{
+  CURL *c;
+  struct CBC cbc;
+  CURLcode errornum;
+  char url[256];
+
+  if (NULL == (cbc.buf = malloc (sizeof (char) * 255)))
+    return 16;
+  cbc.size = 255;
+  cbc.pos = 0;
+
+  gen_test_file_url (url, DEAMON_TEST_PORT);
+
+  /* setup test */
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
+                        MHD_USE_DEBUG, DEAMON_TEST_PORT,
+                        NULL, NULL, &query_session_ahc, NULL,
+			MHD_OPTION_HTTPS_PRIORITIES, "NORMAL:+ARCFOUR-128",
+                        MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
+                        MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
+                        MHD_OPTION_END);
+
+  if (d == NULL)
+    return 2;
+
+  const char *aes256_sha = "AES256-SHA";
+  if (curl_uses_nss_ssl() == 0)
+    {
+      aes256_sha = "rsa_aes_256_sha";
+    }
+
+  c = curl_easy_init ();
+#if DEBUG_HTTPS_TEST
+  curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
+#endif
+  curl_easy_setopt (c, CURLOPT_URL, url);
+  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+  curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L);
+  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 10L);
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_FILE, &cbc);
+  /* TLS options */
+  curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1);
+  curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, aes256_sha);
+  /* currently skip any peer authentication */
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+
+  // 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));
+
+      MHD_stop_daemon (d);
+      curl_easy_cleanup (c);
+      free (cbc.buf);
+      return -1;
+    }
+
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  free (cbc.buf);
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+  if (0 != curl_global_init (CURL_GLOBAL_ALL))
+    {
+      fprintf (stderr, "Error (code: %u)\n", errorCount);
+      return -1;
+    }
+  errorCount += test_query_session ();
+  print_test_result (errorCount, argv[0]);
+  curl_global_cleanup ();
+  if (errorCount > 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  return errorCount;
+}
diff --git a/src/testcurl/https/test_https_sni.c b/src/testcurl/https/test_https_sni.c
new file mode 100644
index 0000000..8c4dea6
--- /dev/null
+++ b/src/testcurl/https/test_https_sni.c
@@ -0,0 +1,291 @@
+/*
+  This file is part of libmicrohttpd
+  Copyright (C) 2013 Christian Grothoff
+
+  libmicrohttpd is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 3, or (at your
+  option) any later version.
+
+  libmicrohttpd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with libmicrohttpd; see the file COPYING.  If not, write to the
+  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+  Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_https_sni.c
+ * @brief  Testcase for libmicrohttpd HTTPS with SNI operations
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "microhttpd.h"
+#include <limits.h>
+#include <sys/stat.h>
+#include <curl/curl.h>
+#include <gcrypt.h>
+#include "tls_test_common.h"
+#include <gnutls/gnutls.h>
+
+/* This test only works with GnuTLS >= 3.0 */
+#if GNUTLS_VERSION_MAJOR >= 3
+
+#include <gnutls/abstract.h>
+
+/**
+ * A hostname, server key and certificate.
+ */
+struct Hosts
+{
+  struct Hosts *next;
+  const char *hostname;
+  gnutls_pcert_st pcrt;
+  gnutls_privkey_t key;
+};
+
+
+/**
+ * Linked list of supported TLDs and respective certificates.
+ */
+static struct Hosts *hosts;
+
+/* Load the certificate and the private key.
+ * (This code is largely taken from GnuTLS).
+ */
+static void
+load_keys(const char *hostname,
+          const char *CERT_FILE,
+          const char *KEY_FILE)
+{
+  int ret;
+  gnutls_datum_t data;
+  struct Hosts *host;
+
+  host = malloc (sizeof (struct Hosts));
+  if (NULL == host)
+    abort ();
+  host->hostname = hostname;
+  host->next = hosts;
+  hosts = host;
+
+  ret = gnutls_load_file (CERT_FILE, &data);
+  if (ret < 0)
+    {
+      fprintf (stderr,
+               "*** Error loading certificate file %s.\n",
+               CERT_FILE);
+      exit (1);
+    }
+  ret =
+    gnutls_pcert_import_x509_raw (&host->pcrt, &data, GNUTLS_X509_FMT_PEM,
+                                  0);
+  if (ret < 0)
+    {
+      fprintf (stderr,
+               "*** Error loading certificate file: %s\n",
+               gnutls_strerror (ret));
+      exit (1);
+    }
+  gnutls_free (data.data);
+
+  ret = gnutls_load_file (KEY_FILE, &data);
+  if (ret < 0)
+    {
+      fprintf (stderr,
+               "*** Error loading key file %s.\n",
+               KEY_FILE);
+      exit (1);
+    }
+
+  gnutls_privkey_init (&host->key);
+  ret =
+    gnutls_privkey_import_x509_raw (host->key,
+                                    &data, GNUTLS_X509_FMT_PEM,
+                                    NULL, 0);
+  if (ret < 0)
+    {
+      fprintf (stderr,
+               "*** Error loading key file: %s\n",
+               gnutls_strerror (ret));
+      exit (1);
+    }
+  gnutls_free (data.data);
+}
+
+
+
+/**
+ * @param session the session we are giving a cert for
+ * @param req_ca_dn NULL on server side
+ * @param nreqs length of req_ca_dn, and thus 0 on server side
+ * @param pk_algos NULL on server side
+ * @param pk_algos_length 0 on server side
+ * @param pcert list of certificates (to be set)
+ * @param pcert_length length of pcert (to be set)
+ * @param pkey the private key (to be set)
+ */
+static int
+sni_callback (gnutls_session_t session,
+              const gnutls_datum_t* req_ca_dn,
+              int nreqs,
+              const gnutls_pk_algorithm_t* pk_algos,
+              int pk_algos_length,
+              gnutls_pcert_st** pcert,
+              unsigned int *pcert_length,
+              gnutls_privkey_t * pkey)
+{
+  char name[256];
+  size_t name_len;
+  struct Hosts *host;
+  unsigned int type;
+
+  name_len = sizeof (name);
+  if (GNUTLS_E_SUCCESS !=
+      gnutls_server_name_get (session,
+                              name,
+                              &name_len,
+                              &type,
+                              0 /* index */))
+    return -1;
+  for (host = hosts; NULL != host; host = host->next)
+    if (0 == strncmp (name, host->hostname, name_len))
+      break;
+  if (NULL == host)
+    {
+      fprintf (stderr,
+               "Need certificate for %.*s\n",
+               (int) name_len,
+               name);
+      return -1;
+    }
+#if 0
+  fprintf (stderr,
+           "Returning certificate for %.*s\n",
+           (int) name_len,
+           name);
+#endif
+  *pkey = host->key;
+  *pcert_length = 1;
+  *pcert = &host->pcrt;
+  return 0;
+}
+
+
+/* perform a HTTP GET request via SSL/TLS */
+static int
+do_get (const char *url)
+{
+  CURL *c;
+  struct CBC cbc;
+  CURLcode errornum;
+  size_t len;
+  struct curl_slist *dns_info;
+
+  len = strlen (test_data);
+  if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
+    {
+      fprintf (stderr, MHD_E_MEM);
+      return -1;
+    }
+  cbc.size = len;
+  cbc.pos = 0;
+
+  c = curl_easy_init ();
+#if DEBUG_HTTPS_TEST
+  curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
+#endif
+  curl_easy_setopt (c, CURLOPT_URL, url);
+  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+  curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L);
+  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 10L);
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_FILE, &cbc);
+
+  /* perform peer authentication */
+  /* TODO merge into send_curl_req */
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 2);
+  dns_info = curl_slist_append (NULL, "host1:4233:127.0.0.1");
+  dns_info = curl_slist_append (dns_info, "host2:4233:127.0.0.1");
+  curl_easy_setopt (c, CURLOPT_RESOLVE, dns_info);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+
+  /* 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);
+      free (cbc.buf);
+      curl_slist_free_all (dns_info);
+      return errornum;
+    }
+
+  curl_easy_cleanup (c);
+  curl_slist_free_all (dns_info);
+  if (memcmp (cbc.buf, test_data, len) != 0)
+    {
+      fprintf (stderr, "Error: local file & received file differ.\n");
+      free (cbc.buf);
+      return -1;
+    }
+
+  free (cbc.buf);
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int error_count = 0;
+  struct MHD_Daemon *d;
+
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+  if (0 != curl_global_init (CURL_GLOBAL_ALL))
+    {
+      fprintf (stderr, "Error: %s\n", strerror (errno));
+      return -1;
+    }
+  load_keys ("host1", ABS_SRCDIR "/host1.crt", ABS_SRCDIR "/host1.key");
+  load_keys ("host2", ABS_SRCDIR "/host2.crt", ABS_SRCDIR "/host2.key");
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | MHD_USE_DEBUG,
+                        4233,
+                        NULL, NULL,
+                        &http_ahc, NULL,
+                        MHD_OPTION_HTTPS_CERT_CALLBACK, &sni_callback,
+                        MHD_OPTION_END);
+  if (d == NULL)
+    {
+      fprintf (stderr, MHD_E_SERVER_INIT);
+      return -1;
+    }
+  error_count += do_get ("https://host1:4233/");
+  error_count += do_get ("https://host2:4233/");
+
+  MHD_stop_daemon (d);
+  curl_global_cleanup ();
+  return error_count != 0;
+}
+
+
+#else
+
+int main ()
+{
+  fprintf (stderr,
+           "SNI not supported by GnuTLS < 3.0\n");
+  return 0;
+}
+#endif
diff --git a/src/testcurl/https/test_https_time_out.c b/src/testcurl/https/test_https_time_out.c
new file mode 100644
index 0000000..124a280
--- /dev/null
+++ b/src/testcurl/https/test_https_time_out.c
@@ -0,0 +1,146 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING.  If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file mhds_get_test.c
+ * @brief: daemon TLS alert response test-case
+ *
+ * @author Sagie Amir
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include "internal.h"
+#include "tls_test_common.h"
+#include <gcrypt.h>
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif /* !WIN32_LEAN_AND_MEAN */
+#include <windows.h>
+#endif
+
+extern const char srv_key_pem[];
+extern const char srv_self_signed_cert_pem[];
+
+static const int TIME_OUT = 3;
+
+static int
+test_tls_session_time_out (gnutls_session_t session)
+{
+  int ret;
+  MHD_socket sd;
+  struct sockaddr_in sa;
+
+  sd = socket (AF_INET, SOCK_STREAM, 0);
+  if (sd == -1)
+    {
+      fprintf (stderr, "Failed to create socket: %s\n", strerror (errno));
+      return -1;
+    }
+
+  memset (&sa, '\0', sizeof (struct sockaddr_in));
+  sa.sin_family = AF_INET;
+  sa.sin_port = htons (DEAMON_TEST_PORT);
+  sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+
+  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (intptr_t) sd);
+
+  ret = connect (sd, &sa, sizeof (struct sockaddr_in));
+
+  if (ret < 0)
+    {
+      fprintf (stderr, "Error: %s\n", MHD_E_FAILED_TO_CONNECT);
+      close (sd);
+      return -1;
+    }
+
+  ret = gnutls_handshake (session);
+  if (ret < 0)
+    {
+      fprintf (stderr, "Handshake failed\n");
+      close (sd);
+      return -1;
+    }
+
+  sleep (TIME_OUT + 1);
+
+  /* check that server has closed the connection */
+  /* TODO better RST trigger */
+  if (send (sd, "", 1, 0) == 0)
+    {
+      fprintf (stderr, "Connection failed to time-out\n");
+      close (sd);
+      return -1;
+    }
+
+  close (sd);
+  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;
+
+
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+  gnutls_global_init ();
+  gnutls_global_set_log_level (11);
+
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
+                        MHD_USE_DEBUG, DEAMON_TEST_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 (d == NULL)
+    {
+      fprintf (stderr, MHD_E_SERVER_INIT);
+      return -1;
+    }
+
+  if (0 != setup_session (&session, &key, &cert, &xcred))
+    {
+      fprintf (stderr, "failed to setup session\n");
+      return 1;
+    }
+  errorCount += test_tls_session_time_out (session);
+  teardown_session (session, &key, &cert, xcred);
+
+  print_test_result (errorCount, argv[0]);
+
+  MHD_stop_daemon (d);
+  gnutls_global_deinit ();
+
+  return errorCount != 0;
+}
diff --git a/src/testcurl/https/test_tls_authentication.c b/src/testcurl/https/test_tls_authentication.c
new file mode 100644
index 0000000..cc9c76d
--- /dev/null
+++ b/src/testcurl/https/test_tls_authentication.c
@@ -0,0 +1,110 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING.  If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file tls_authentication_test.c
+ * @brief  Testcase for libmicrohttpd HTTPS GET operations
+ * @author Sagie Amir
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include <curl/curl.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <gcrypt.h>
+#include "tls_test_common.h"
+
+extern int curl_check_version (const char *req_version, ...);
+extern const char test_file_data[];
+
+extern const char ca_key_pem[];
+extern const char ca_cert_pem[];
+extern const char srv_signed_cert_pem[];
+extern const char srv_signed_key_pem[];
+
+
+
+/* perform a HTTP GET request via SSL/TLS */
+static int
+test_secure_get (void * cls, char *cipher_suite, int proto_version)
+{
+  int ret;
+  struct MHD_Daemon *d;
+
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
+                        MHD_USE_DEBUG, DEAMON_TEST_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;
+    }
+
+  ret = test_daemon_get (NULL, cipher_suite, proto_version, DEAMON_TEST_PORT, 0);
+
+  MHD_stop_daemon (d);
+  return ret;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+  if (setup_ca_cert () == NULL)
+    {
+      fprintf (stderr, MHD_E_TEST_FILE_CREAT);
+      return -1;
+    }
+
+  if (0 != curl_global_init (CURL_GLOBAL_ALL))
+    {
+      fprintf (stderr, "Error (code: %u)\n", errorCount);
+      return -1;
+    }
+
+  char *aes256_sha = "AES256-SHA";
+  if (curl_uses_nss_ssl() == 0)
+    {
+      aes256_sha = "rsa_aes_256_sha";
+    }
+
+  errorCount +=
+    test_secure_get (NULL, aes256_sha, CURL_SSLVERSION_TLSv1);
+
+  print_test_result (errorCount, argv[0]);
+
+  curl_global_cleanup ();
+  if (0 != remove (ca_cert_file_name))
+    fprintf (stderr,
+	     "Failed to remove `%s'\n",
+	     ca_cert_file_name);
+  return errorCount != 0;
+}
diff --git a/src/testcurl/https/test_tls_options.c b/src/testcurl/https/test_tls_options.c
new file mode 100644
index 0000000..7dd01a7
--- /dev/null
+++ b/src/testcurl/https/test_tls_options.c
@@ -0,0 +1,155 @@
+/*
+  This file is part of libmicrohttpd
+  Copyright (C) 2007, 2010 Christian Grothoff
+  
+  libmicrohttpd is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2, or (at your
+  option) any later version.
+  
+  libmicrohttpd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  General Public License for more details.
+  
+  You should have received a copy of the GNU General Public License
+  along with libmicrohttpd; see the file COPYING.  If not, write to the
+  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+  Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file tls_daemon_options_test.c
+ * @brief  Testcase for libmicrohttpd HTTPS GET operations
+ * @author Sagie Amir
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+#include <sys/stat.h>
+#include <limits.h>
+#include <gcrypt.h>
+#include "tls_test_common.h"
+
+extern const char srv_key_pem[];
+extern const char srv_self_signed_cert_pem[];
+
+int curl_check_version (const char *req_version, ...);
+
+/**
+ * test server refuses to negotiate connections with unsupported protocol versions
+ *
+ */
+static int
+test_unmatching_ssl_version (void * cls, const char *cipher_suite,
+                             int curl_req_ssl_version)
+{
+  struct CBC cbc;
+  if (NULL == (cbc.buf = malloc (sizeof (char) * 256)))
+    {
+      fprintf (stderr, "Error: failed to allocate: %s\n",
+               strerror (errno));
+      return -1;
+    }
+  cbc.size = 256;
+  cbc.pos = 0;
+
+  char url[255];
+  if (gen_test_file_url (url, DEAMON_TEST_PORT))
+    {
+      free (cbc.buf);
+      fprintf (stderr, "Internal error in gen_test_file_url\n");
+      return -1;
+    }
+
+  /* assert daemon *rejected* request */
+  if (CURLE_OK ==
+      send_curl_req (url, &cbc, cipher_suite, curl_req_ssl_version))
+    {
+      free (cbc.buf);
+      fprintf (stderr, "cURL failed to reject request despite SSL version missmatch!\n");
+      return -1;
+    }
+
+  free (cbc.buf);
+  return 0;
+}
+
+
+/* setup a temporary transfer test file */
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+  const char *ssl_version;
+  int daemon_flags =
+    MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | MHD_USE_DEBUG;
+
+  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+ if (curl_check_version (MHD_REQ_CURL_VERSION))
+    {
+      return 0;
+    }
+  ssl_version = curl_version_info (CURLVERSION_NOW)->ssl_version;
+  if (NULL == ssl_version)
+  {
+    fprintf (stderr, "Curl does not support SSL.  Cannot run the test.\n");
+    return 0;
+  }
+  if (0 != strncmp (ssl_version, "GnuTLS", 6))
+  {
+    fprintf (stderr, "This test can be run only with libcurl-gnutls.\n");
+    return 0;
+  }
+
+  if (0 != curl_global_init (CURL_GLOBAL_ALL))
+    {
+      fprintf (stderr, "Error: %s\n", strerror (errno));
+      return 0; 
+    }
+
+  const char *aes128_sha = "AES128-SHA";
+  const char *aes256_sha = "AES256-SHA";
+  if (curl_uses_nss_ssl() == 0)
+    {
+      aes128_sha = "rsa_aes_128_sha";
+      aes256_sha = "rsa_aes_256_sha";
+    }
+  
+
+  if (0 != 
+    test_wrap ("TLS1.0-AES-SHA1",
+	       &test_https_transfer, NULL, daemon_flags,
+	       aes128_sha,
+	       CURL_SSLVERSION_TLSv1,
+	       MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
+	       MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
+	       MHD_OPTION_HTTPS_PRIORITIES, "NONE:+VERS-TLS1.0:+AES-128-CBC:+SHA1:+RSA:+COMP-NULL",
+	       MHD_OPTION_END))
+    {
+      fprintf (stderr, "TLS1.0-AES-SHA1 test failed\n");
+      errorCount++;
+    }
+  fprintf (stderr,
+	   "The following handshake should fail (and print an error message)...\n");
+  if (0 !=
+    test_wrap ("TLS1.0 vs SSL3",
+	       &test_unmatching_ssl_version, NULL, daemon_flags,
+	       aes256_sha,
+	       CURL_SSLVERSION_SSLv3,
+	       MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
+	       MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
+	       MHD_OPTION_HTTPS_PRIORITIES, "NONE:+VERS-TLS1.0:+AES-256-CBC:+SHA1:+RSA:+COMP-NULL",
+	       MHD_OPTION_END))
+    {
+      fprintf (stderr, "TLS1.0 vs SSL3 test failed\n");
+      errorCount++;
+    }
+  curl_global_cleanup ();
+
+  return errorCount != 0;
+}
diff --git a/src/testcurl/https/tls_test_common.c b/src/testcurl/https/tls_test_common.c
new file mode 100644
index 0000000..f917582
--- /dev/null
+++ b/src/testcurl/https/tls_test_common.c
@@ -0,0 +1,484 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING.  If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file tls_test_common.c
+ * @brief  Common tls test functions
+ * @author Sagie Amir
+ */
+#include "tls_test_common.h"
+#include "tls_test_keys.h"
+
+
+int curl_check_version (const char *req_version, ...);
+
+FILE *
+setup_ca_cert ()
+{
+  FILE *cert_fd;
+
+  if (NULL == (cert_fd = fopen (ca_cert_file_name, "wb+")))
+    {
+      fprintf (stderr, "Error: failed to open `%s': %s\n",
+               ca_cert_file_name, strerror (errno));
+      return NULL;
+    }
+  if (fwrite (ca_cert_pem, sizeof (char), strlen (ca_cert_pem) + 1, cert_fd)
+      != strlen (ca_cert_pem) + 1)
+    {
+      fprintf (stderr, "Error: failed to write `%s. %s'\n",
+               ca_cert_file_name, strerror (errno));
+      fclose (cert_fd);
+      return NULL;
+    }
+  if (fflush (cert_fd))
+    {
+      fprintf (stderr, "Error: failed to flush ca cert file stream. %s\n",
+               strerror (errno));
+      fclose (cert_fd);
+      return NULL;
+    }
+  return cert_fd;
+}
+
+
+/*
+ * test HTTPS transfer
+ */
+int
+test_daemon_get (void *cls,
+		 const char *cipher_suite, int proto_version,
+		 int port,
+		 int ver_peer)
+{
+  CURL *c;
+  struct CBC cbc;
+  CURLcode errornum;
+  char url[255];
+  size_t len;
+
+  len = strlen (test_data);
+  if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
+    {
+      fprintf (stderr, MHD_E_MEM);
+      return -1;
+    }
+  cbc.size = len;
+  cbc.pos = 0;
+
+  /* construct url - this might use doc_path */
+  gen_test_file_url (url, port);
+
+  c = curl_easy_init ();
+#if DEBUG_HTTPS_TEST
+  curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
+#endif
+  curl_easy_setopt (c, CURLOPT_URL, url);
+  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+  curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L);
+  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 10L);
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_FILE, &cbc);
+
+  /* TLS options */
+  curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version);
+  curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
+
+  /* perform peer authentication */
+  /* TODO merge into send_curl_req */
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, ver_peer);
+  curl_easy_setopt (c, CURLOPT_CAINFO, ca_cert_file_name);
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  
+  /* 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);
+      free (cbc.buf);
+      return errornum;
+    }
+
+  curl_easy_cleanup (c);
+
+  if (memcmp (cbc.buf, test_data, len) != 0)
+    {
+      fprintf (stderr, "Error: local file & received file differ.\n");
+      free (cbc.buf);
+      return -1;
+    }
+
+  free (cbc.buf);
+  return 0;
+}
+
+
+void
+print_test_result (int test_outcome, char *test_name)
+{
+#if 0
+  if (test_outcome != 0)
+    fprintf (stderr, "running test: %s [fail]\n", test_name);
+  else
+    fprintf (stdout, "running test: %s [pass]\n", test_name);
+#endif
+}
+
+size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+/**
+ *  HTTP access handler call back
+ */
+int
+http_ahc (void *cls, struct MHD_Connection *connection,
+          const char *url, const char *method, const char *upload_data,
+          const char *version, size_t *upload_data_size, void **ptr)
+{
+  static int aptr;
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
+    return MHD_NO;              /* unexpected method */
+  if (&aptr != *ptr)
+    {
+      /* do never respond on first call */
+      *ptr = &aptr;
+      return MHD_YES;
+    }
+  *ptr = NULL;                  /* reset when done */
+  response = MHD_create_response_from_buffer (strlen (test_data),
+					      (void *) test_data,
+					      MHD_RESPMEM_PERSISTENT);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  return ret;
+}
+
+/* HTTP access handler call back */
+int
+http_dummy_ahc (void *cls, struct MHD_Connection *connection,
+                const char *url, const char *method, const char *upload_data,
+                const char *version, size_t *upload_data_size,
+                void **ptr)
+{
+  return 0;
+}
+
+/**
+ * send a test http request to the daemon
+ * @param url
+ * @param cbc - may be null
+ * @param cipher_suite
+ * @param proto_version
+ * @return
+ */
+/* TODO have test wrap consider a NULL cbc */
+int
+send_curl_req (char *url, struct CBC * cbc, const char *cipher_suite,
+               int proto_version)
+{
+  CURL *c;
+  CURLcode errornum;
+  c = curl_easy_init ();
+#if DEBUG_HTTPS_TEST
+  curl_easy_setopt (c, CURLOPT_VERBOSE, CURL_VERBOS_LEVEL);
+#endif
+  curl_easy_setopt (c, CURLOPT_URL, url);
+  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+  curl_easy_setopt (c, CURLOPT_TIMEOUT, 60L);
+  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 60L);
+
+  if (cbc != NULL)
+    {
+      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+      curl_easy_setopt (c, CURLOPT_FILE, cbc);
+    }
+
+  /* TLS options */
+  curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version);
+  curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
+
+  /* currently skip any peer authentication */
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
+  curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
+
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+
+  /* 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);
+      return errornum;
+    }
+  curl_easy_cleanup (c);
+
+  return CURLE_OK;
+}
+
+
+/**
+ * compile test file url pointing to the current running directory path
+ *
+ * @param url - char buffer into which the url is compiled
+ * @param port port to use for the test
+ * @return -1 on error
+ */
+int
+gen_test_file_url (char *url, int port)
+{
+  int ret = 0;
+  char *doc_path;
+  size_t doc_path_len;
+  /* setup test file path, url */
+  doc_path_len = PATH_MAX > 4096 ? 4096 : PATH_MAX;
+  if (NULL == (doc_path = malloc (doc_path_len)))
+    {
+      fprintf (stderr, MHD_E_MEM);
+      return -1;
+    }
+  if (getcwd (doc_path, doc_path_len) == NULL)
+    {
+      fprintf (stderr, "Error: failed to get working directory. %s\n",
+               strerror (errno));
+      ret = -1;
+    }
+#ifdef WINDOWS
+  {
+    int i;
+    for (i = 0; i < doc_path_len; i++)
+    {
+      if (doc_path[i] == 0)
+        break;
+      if (doc_path[i] == '\\')
+      {
+        doc_path[i] = '/';
+      }
+      if (doc_path[i] != ':')
+        continue;
+      if (i == 0)
+        break;
+      doc_path[i] = doc_path[i - 1];
+      doc_path[i - 1] = '/';
+    }
+  }
+#endif
+  /* construct url - this might use doc_path */
+  if (sprintf (url, "%s:%d%s/%s", "https://127.0.0.1", port,
+               doc_path, "urlpath") < 0)
+    ret = -1;
+
+  free (doc_path);
+  return ret;
+}
+
+/**
+ * test HTTPS file transfer
+ */
+int
+test_https_transfer (void *cls, const char *cipher_suite, int proto_version)
+{
+  int len;
+  int ret = 0;
+  struct CBC cbc;
+  char url[255];
+
+  len = strlen (test_data);
+  if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
+    {
+      fprintf (stderr, MHD_E_MEM);
+      return -1;
+    }
+  cbc.size = len;
+  cbc.pos = 0;
+
+  if (gen_test_file_url (url, DEAMON_TEST_PORT))
+    {
+      ret = -1;
+      goto cleanup;
+    }
+
+  if (CURLE_OK != send_curl_req (url, &cbc, cipher_suite, proto_version))
+    {
+      ret = -1;
+      goto cleanup;
+    }
+
+  /* compare test file & daemon responce */
+  if ( (len != strlen (test_data)) ||
+       (memcmp (cbc.buf, 
+		test_data, 
+		len) != 0) )
+    {
+      fprintf (stderr, "Error: local file & received file differ.\n");
+      ret = -1;
+    }
+cleanup:
+  free (cbc.buf);
+  return ret;
+}
+
+/**
+ * setup test case
+ *
+ * @param d
+ * @param daemon_flags
+ * @param arg_list
+ * @return
+ */
+int
+setup_testcase (struct MHD_Daemon **d, int daemon_flags, va_list arg_list)
+{
+  *d = MHD_start_daemon_va (daemon_flags, DEAMON_TEST_PORT,
+                            NULL, NULL, &http_ahc, NULL, arg_list);
+
+  if (*d == NULL)
+    {
+      fprintf (stderr, MHD_E_SERVER_INIT);
+      return -1;
+    }
+
+  return 0;
+}
+
+void
+teardown_testcase (struct MHD_Daemon *d)
+{
+  MHD_stop_daemon (d);
+}
+
+int
+setup_session (gnutls_session_t * session,
+               gnutls_datum_t * key,
+               gnutls_datum_t * cert, 
+	       gnutls_certificate_credentials_t * xcred)
+{
+  int ret;
+  const char *err_pos;
+
+  gnutls_certificate_allocate_credentials (xcred);
+  key->size = strlen (srv_key_pem) + 1;
+  key->data = malloc (key->size);
+  if (NULL == key->data) 
+     {
+       gnutls_certificate_free_credentials (*xcred);
+	return -1;
+     }
+  memcpy (key->data, srv_key_pem, key->size);
+  cert->size = strlen (srv_self_signed_cert_pem) + 1;
+  cert->data = malloc (cert->size);
+  if (NULL == cert->data)
+    {
+        gnutls_certificate_free_credentials (*xcred);
+	free (key->data); 
+	return -1;
+    }
+  memcpy (cert->data, srv_self_signed_cert_pem, cert->size);
+  gnutls_certificate_set_x509_key_mem (*xcred, cert, key,
+				       GNUTLS_X509_FMT_PEM);
+  gnutls_init (session, GNUTLS_CLIENT);
+  ret = gnutls_priority_set_direct (*session,
+				    "NORMAL", &err_pos);
+  if (ret < 0)
+    {
+       gnutls_deinit (*session);
+       gnutls_certificate_free_credentials (*xcred);
+       free (key->data);
+       return -1;
+    }
+  gnutls_credentials_set (*session, 
+			  GNUTLS_CRD_CERTIFICATE, 
+			  *xcred);
+  return 0;
+}
+
+int
+teardown_session (gnutls_session_t session,
+                  gnutls_datum_t * key,
+                  gnutls_datum_t * cert,
+                  gnutls_certificate_credentials_t xcred)
+{
+  free (key->data);
+  key->data = NULL;
+  key->size = 0;
+  free (cert->data);
+  cert->data = NULL;
+  cert->size = 0;
+  gnutls_deinit (session);
+  gnutls_certificate_free_credentials (xcred);
+  return 0;
+}
+
+/* TODO test_wrap: change sig to (setup_func, test, va_list test_arg) */
+int
+test_wrap (const char *test_name, int
+           (*test_function) (void * cls, const char *cipher_suite,
+                             int proto_version), void * cls,
+           int daemon_flags, const char *cipher_suite, int proto_version, ...)
+{
+  int ret;
+  va_list arg_list;
+  struct MHD_Daemon *d;
+
+  va_start (arg_list, proto_version);
+  if (setup_testcase (&d, daemon_flags, arg_list) != 0)
+    {
+      va_end (arg_list);
+      fprintf (stderr, "Failed to setup testcase %s\n", test_name);
+      return -1;
+    }
+#if 0
+  fprintf (stdout, "running test: %s ", test_name);
+#endif
+  ret = test_function (NULL, cipher_suite, proto_version);
+#if 0
+  if (ret == 0)
+    {
+      fprintf (stdout, "[pass]\n");
+    }
+  else
+    {
+      fprintf (stdout, "[fail]\n");
+    }
+#endif
+  teardown_testcase (d);
+  va_end (arg_list);
+  return ret;
+}
diff --git a/src/testcurl/https/tls_test_common.h b/src/testcurl/https/tls_test_common.h
new file mode 100644
index 0000000..20198f7
--- /dev/null
+++ b/src/testcurl/https/tls_test_common.h
@@ -0,0 +1,141 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING.  If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+#ifndef TLS_TEST_COMMON_H_
+#define TLS_TEST_COMMON_H_
+
+#include "platform.h"
+#include "microhttpd.h"
+#include <curl/curl.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <gnutls/gnutls.h>
+
+/* this enables verbos CURL version checking */
+#define DEBUG_HTTPS_TEST 0
+#define CURL_VERBOS_LEVEL 0
+
+#define DEAMON_TEST_PORT 4233
+
+#define test_data "Hello World\n"
+#define ca_cert_file_name "tmp_ca_cert.pem"
+
+#define EMPTY_PAGE "<html><head><title>Empty page</title></head><body>Empty page</body></html>"
+#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
+
+#define MHD_E_MEM "Error: memory error\n"
+#define MHD_E_SERVER_INIT "Error: failed to start server\n"
+#define MHD_E_TEST_FILE_CREAT "Error: failed to setup test file\n"
+#define MHD_E_CERT_FILE_CREAT "Error: failed to setup test certificate\n"
+#define MHD_E_KEY_FILE_CREAT "Error: failed to setup test certificate\n"
+#define MHD_E_FAILED_TO_CONNECT "Error: server connection could not be established\n"
+
+/* TODO rm if unused */
+struct https_test_data
+{
+  void *cls;
+  const char *cipher_suite;
+  int proto_version;
+};
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+struct CipherDef
+{
+  int options[2];
+  char *curlname;
+};
+
+
+int curl_check_version (const char *req_version, ...);
+int curl_uses_nss_ssl ();
+
+
+FILE *
+setup_ca_cert ();
+
+/**
+ * perform cURL request for file
+ */
+int
+test_daemon_get (void * cls,
+		 const char *cipher_suite, int proto_version,
+                 int port, int ver_peer);
+
+void print_test_result (int test_outcome, char *test_name);
+
+size_t copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx);
+
+int
+http_ahc (void *cls, struct MHD_Connection *connection,
+          const char *url, const char *method, const char *upload_data,
+          const char *version, size_t *upload_data_size, void **ptr);
+
+int
+http_dummy_ahc (void *cls, struct MHD_Connection *connection,
+                const char *url, const char *method, const char *upload_data,
+                const char *version, size_t *upload_data_size,
+                void **ptr);
+
+
+/**
+ * compile test file url pointing to the current running directory path
+ *
+ * @param url - char buffer into which the url is compiled
+ * @param port port to use for the test
+ * @return -1 on error
+ */
+int gen_test_file_url (char *url, int port);
+
+int
+send_curl_req (char *url, struct CBC *cbc, const char *cipher_suite,
+               int proto_version);
+
+int
+test_https_transfer (void *cls, const char *cipher_suite, int proto_version);
+
+int
+setup_testcase (struct MHD_Daemon **d, int daemon_flags, va_list arg_list);
+
+void teardown_testcase (struct MHD_Daemon *d);
+
+int
+setup_session (gnutls_session_t * session,
+               gnutls_datum_t * key,
+               gnutls_datum_t * cert,
+               gnutls_certificate_credentials_t * xcred);
+
+int
+teardown_session (gnutls_session_t session,
+                  gnutls_datum_t * key,
+                  gnutls_datum_t * cert,
+                  gnutls_certificate_credentials_t xcred);
+
+int
+test_wrap (const char *test_name, int
+           (*test_function) (void * cls, const char *cipher_suite,
+                             int proto_version), void *test_function_cls,
+           int daemon_flags, const char *cipher_suite, int proto_version, ...);
+#endif /* TLS_TEST_COMMON_H_ */
diff --git a/src/testcurl/https/tls_test_keys.h b/src/testcurl/https/tls_test_keys.h
new file mode 100644
index 0000000..b6e37ee
--- /dev/null
+++ b/src/testcurl/https/tls_test_keys.h
@@ -0,0 +1,173 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2006, 2007, 2008 Christian Grothoff (and other contributing authors)
+
+     This library is free software; you can redistribute it and/or
+     modify it under the terms of the GNU Lesser General Public
+     License as published by the Free Software Foundation; either
+     version 2.1 of the License, or (at your option) any later version.
+
+     This library is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     Lesser General Public License for more details.
+
+     You should have received a copy of the GNU Lesser General Public
+     License along with this library; if not, write to the Free Software
+     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef MHD_TLS_TEST_KEYS_H
+#define MHD_TLS_TEST_KEYS_H
+
+/* Test Certificates */
+
+/* Certificate Authority key */
+const char ca_key_pem[] = "-----BEGIN RSA PRIVATE KEY-----\n"
+  "MIIEowIBAAKCAQEA0EdlP613rjFvEj93tGo9fzBoKWU3CW+AbbfcJ397C89MyZ9J\n"
+  "rlxyLGfa6qVX7CFVNmzgWWfcl2tHlw/fZmWtf/SFgrlkldvuGyY8H3n2HuMsWz/E\n"
+  "h7n5VgwBX8NsP4eZNmikepxpr1mYx25K8FjnsKjAR9jGUSV8UfZ7VLIY0x/yqe+3\n"
+  "32oqc4D/wJbV1AwwvC5Xf9rvHJwcZg57eqbDCL/4GDDk7d9Gark4XK6ZG+FnnxQn\n"
+  "4a4jIdf4FoPp9s0EieHrHwYzs/uBqmfCSF4wXiaO8bmEwtbAsVbZH74Le7ggUbEe\n"
+  "o+jan9XK0dE88AIImGzgoBnlic/Rr7J8OWA+iwIDAQABAoIBAEICZqXkUdpsw2F6\n"
+  "qPMOergNPO3lrKg6ZO8hBs6j2fj3tcPuzljK5sqJDboxNejZ9Zo+rmnXf3Oj5fgL\n"
+  "6UcYMYEsm4W/QRA3uEJ1fzeQnT7Ty9KNprlHaSzquCLEGlIWJSo3xu0vFlWjJUcL\n"
+  "fwemfaOhD/OVUeEU6s5FOngwy6pZUsOajs3fNRtwBGuuXjniKZZlpSf2Wqu3xpHZ\n"
+  "31OF1V0ycUCGPPFtpmUCtnZhS9L8QBTkNtfTIdXv6SfoBRFm0oXb0uL5HGft6yc7\n"
+  "eYRXIscllQciqG3ymJ/y9o0E3A0YsBVauQyi7OEk+Kg8uoYOBkZCIY69hoN2Znlk\n"
+  "OY5S5Z0CgYEA3j8pRAJzvc827KcX4vJf05HYD4aCyaI80fNmx1DgXfglTSGLQ361\n"
+  "6i05YW8WtIvgkma3wF+jJOckBCW/7iq8wAX7Kz75WKGRyyTEb0wSfjx0G8grxX4d\n"
+  "7sTIAAOnQj5WT6E/bkqxQZAYnVtIPxKtSlwts0H/bjPVYwSFchHK7t8CgYEA7+ks\n"
+  "C0EMjF8CDeCfvbOUGiiqAvU3G20LEC3WlJM3AU+J9Jzp6AMkgaIA8J5oNdsbFBn4\n"
+  "N12JPOO+7WRUk6Av8bsh4faE36ThnHohgAL8guRU7jIXvsFyO5yiY7/o/0lES0/V\n"
+  "6xkh/Epj4MReuCGkiD9ifCVAo+dhHskeE9qbYdUCgYA4yBpa7eV0UUTPIcHQkew5\n"
+  "ucFh9hPkQDcZzP4tXlR0rbmaAz/5dp4zvmoyopdCeZpezS+VTtn3y7Y/+QUYbILc\n"
+  "7KpHWkeKhX0iUbp+VQlEh12C25mTU62CG3SdzFEnc5XJsoDqRNsUzSP80B2dP8BW\n"
+  "h0aFzg7csRGLwtP1WOZoMQKBgQCrgsKd+Q8Dexh421DXyX3jhZalLrEKxlXWZy60\n"
+  "YNo98aLqYRNHbpe2pR6O5nARsGYXZMlyq0flY9um0sc0Epyz79g1NoufZrxzpUw1\n"
+  "u+zRlnKxJtaa5KjJvRzKuvPTLYnJXXXM8Na/Cl+E3F3qvQJm9QlvPyKLCmsAGz+J\n"
+  "agsTUQKBgC0wqqJ6b1tbrAD8AVeeAn/IiP1rxYpc3x2s6ikFO2FMHXHC9wgrRPOc\n"
+  "mkokV+DrUOv3I/7jG8wQA/FmBUPy562a1bObIKzg6CPXzrN68AmNnOIVU+H8fdxI\n"
+  "iGyfT8WNpcRmtN11v34qXHwOWGQhpyyk2yNa8VIBSpkShq/EseZ1\n"
+  "-----END RSA PRIVATE KEY-----\n";
+
+/* Certificate Authority cert */
+const char ca_cert_pem[] = "-----BEGIN CERTIFICATE-----\n"
+  "MIIC6DCCAdKgAwIBAgIES0KCvTALBgkqhkiG9w0BAQUwFzEVMBMGA1UEAxMMdGVz\n"
+  "dF9jYV9jZXJ0MB4XDTEwMDEwNTAwMDcyNVoXDTQ1MDMxMjAwMDcyNVowFzEVMBMG\n"
+  "A1UEAxMMdGVzdF9jYV9jZXJ0MIIBHzALBgkqhkiG9w0BAQEDggEOADCCAQkCggEA\n"
+  "0EdlP613rjFvEj93tGo9fzBoKWU3CW+AbbfcJ397C89MyZ9JrlxyLGfa6qVX7CFV\n"
+  "NmzgWWfcl2tHlw/fZmWtf/SFgrlkldvuGyY8H3n2HuMsWz/Eh7n5VgwBX8NsP4eZ\n"
+  "Nmikepxpr1mYx25K8FjnsKjAR9jGUSV8UfZ7VLIY0x/yqe+332oqc4D/wJbV1Aww\n"
+  "vC5Xf9rvHJwcZg57eqbDCL/4GDDk7d9Gark4XK6ZG+FnnxQn4a4jIdf4FoPp9s0E\n"
+  "ieHrHwYzs/uBqmfCSF4wXiaO8bmEwtbAsVbZH74Le7ggUbEeo+jan9XK0dE88AII\n"
+  "mGzgoBnlic/Rr7J8OWA+iwIDAQABo0MwQTAPBgNVHRMBAf8EBTADAQH/MA8GA1Ud\n"
+  "DwEB/wQFAwMHBAAwHQYDVR0OBBYEFP2olB4s2T/xuoQ5pT2RKojFwZo2MAsGCSqG\n"
+  "SIb3DQEBBQOCAQEAebD5m+vZkVXa8y+QZ5GtsiR9gpH+LKtdWBjk1kmfSgvQI/xA\n"
+  "aDCV/9BhdNGIBOTYGkln8urWd7g2Mj3TwKEAfNTUFpAsrBAlSSLTGYCSt72S2NsS\n"
+  "L/qUxmj1W6X95UHXCo49mSZx3LlaY3mz1L87gq/kK0XpzA3g2uF25jt84RvshsXy\n"
+  "clOc+eRrVETqFZqer96WB7kzFTv+qmROQKmW8X4a2A5r5Jl4vRwOz5/rEeB9Qs0K\n"
+  "rmK8+5HgvWd80WB8BtfFtZfoY/hHVM8nLD3ELVJrOKiTeIACunQFyT5lV0QkdmSA\n"
+  "CGInU7jzs8nu+s2avf6j+eVZUbVJ+dFMApTJgg==\n"
+  "-----END CERTIFICATE-----\n";
+
+/* test server CA signed certificates */
+const char srv_signed_cert_pem[] = "-----BEGIN CERTIFICATE-----\n"
+  "MIIDGzCCAgWgAwIBAgIES0KCvTALBgkqhkiG9w0BAQUwFzEVMBMGA1UEAxMMdGVz\n"
+  "dF9jYV9jZXJ0MB4XDTEwMDEwNTAwMDcyNVoXDTQ1MDMxMjAwMDcyNVowFzEVMBMG\n"
+  "A1UEAxMMdGVzdF9jYV9jZXJ0MIIBHzALBgkqhkiG9w0BAQEDggEOADCCAQkCggEA\n"
+  "vfTdv+3fgvVTKRnP/HVNG81cr8TrUP/iiyuve/THMzvFXhCW+K03KwEku55QvnUn\n"
+  "dwBfU/ROzLlv+5hotgiDRNFT3HxurmhouySBrJNJv7qWp8ILq4sw32vo0fbMu5BZ\n"
+  "F49bUXK9L3kW2PdhTtSQPWHEzNrCxO+YgCilKHkY3vQNfdJ020Q5EAAEseD1YtWC\n"
+  "IpRvJzYlZMpjYB1ubTl24kwrgOKUJYKqM4jmF4DVQp4oOK/6QYGGh1QmHRPAy3CB\n"
+  "II6sbb+sZT9cAqU6GYQVB35lm4XAgibXV6KgmpVxVQQ69U6xyoOl204xuekZOaG9\n"
+  "RUPId74Rtmwfi1TLbBzo2wIDAQABo3YwdDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQM\n"
+  "MAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMHIAAwHQYDVR0OBBYEFOFi4ilKOP1d\n"
+  "XHlWCMwmVKr7mgy8MB8GA1UdIwQYMBaAFP2olB4s2T/xuoQ5pT2RKojFwZo2MAsG\n"
+  "CSqGSIb3DQEBBQOCAQEAHVWPxazupbOkG7Did+dY9z2z6RjTzYvurTtEKQgzM2Vz\n"
+  "GQBA+3pZ3c5mS97fPIs9hZXfnQeelMeZ2XP1a+9vp35bJjZBBhVH+pqxjCgiUflg\n"
+  "A3Zqy0XwwVCgQLE2HyaU3DLUD/aeIFK5gJaOSdNTXZLv43K8kl4cqDbMeRpVTbkt\n"
+  "YmG4AyEOYRNKGTqMEJXJoxD5E3rBUNrVI/XyTjYrulxbNPcMWEHKNeeqWpKDYTFo\n"
+  "Bb01PCthGXiq/4A2RLAFosadzRa8SBpoSjPPfZ0b2w4MJpReHqKbR5+T2t6hzml6\n"
+  "4ToyOKPDmamiTuN5KzLN3cw7DQlvWMvqSOChPLnA3Q==\n"
+  "-----END CERTIFICATE-----\n";
+
+/* test server key */
+const char srv_signed_key_pem[] = "-----BEGIN RSA PRIVATE KEY-----\n"
+  "MIIEowIBAAKCAQEAvfTdv+3fgvVTKRnP/HVNG81cr8TrUP/iiyuve/THMzvFXhCW\n"
+  "+K03KwEku55QvnUndwBfU/ROzLlv+5hotgiDRNFT3HxurmhouySBrJNJv7qWp8IL\n"
+  "q4sw32vo0fbMu5BZF49bUXK9L3kW2PdhTtSQPWHEzNrCxO+YgCilKHkY3vQNfdJ0\n"
+  "20Q5EAAEseD1YtWCIpRvJzYlZMpjYB1ubTl24kwrgOKUJYKqM4jmF4DVQp4oOK/6\n"
+  "QYGGh1QmHRPAy3CBII6sbb+sZT9cAqU6GYQVB35lm4XAgibXV6KgmpVxVQQ69U6x\n"
+  "yoOl204xuekZOaG9RUPId74Rtmwfi1TLbBzo2wIDAQABAoIBADu09WSICNq5cMe4\n"
+  "+NKCLlgAT1NiQpLls1gKRbDhKiHU9j8QWNvWWkJWrCya4QdUfLCfeddCMeiQmv3K\n"
+  "lJMvDs+5OjJSHFoOsGiuW2Ias7IjnIojaJalfBml6frhJ84G27IXmdz6gzOiTIer\n"
+  "DjeAgcwBaKH5WwIay2TxIaScl7AwHBauQkrLcyb4hTmZuQh6ArVIN6+pzoVuORXM\n"
+  "bpeNWl2l/HSN3VtUN6aCAKbN/X3o0GavCCMn5Fa85uJFsab4ss/uP+2PusU71+zP\n"
+  "sBm6p/2IbGvF5k3VPDA7X5YX61sukRjRBihY8xSnNYx1UcoOsX6AiPnbhifD8+xQ\n"
+  "Tlf8oJUCgYEA0BTfzqNpr9Wxw5/QXaSdw7S/0eP5a0C/nwURvmfSzuTD4equzbEN\n"
+  "d+dI/s2JMxrdj/I4uoAfUXRGaabevQIjFzC9uyE3LaOyR2zhuvAzX+vVcs6bSXeU\n"
+  "pKpCAcN+3Z3evMaX2f+z/nfSUAl2i4J2R+/LQAWJW4KwRky/m+cxpfUCgYEA6bN1\n"
+  "b73bMgM8wpNt6+fcmS+5n0iZihygQ2U2DEud8nZJL4Nrm1dwTnfZfJBnkGj6+0Q0\n"
+  "cOwj2KS0/wcEdJBP0jucU4v60VMhp75AQeHqidIde0bTViSRo3HWKXHBIFGYoU3T\n"
+  "LyPyKndbqsOObnsFXHn56Nwhr2HLf6nw4taGQY8CgYBoSW36FLCNbd6QGvLFXBGt\n"
+  "2lMhEM8az/K58kJ4WXSwOLtr6MD/WjNT2tkcy0puEJLm6BFCd6A6pLn9jaKou/92\n"
+  "SfltZjJPb3GUlp9zn5tAAeSSi7YMViBrfuFiHObij5LorefBXISLjuYbMwL03MgH\n"
+  "Ocl2JtA2ywMp2KFXs8GQWQKBgFyIVv5ogQrbZ0pvj31xr9HjqK6d01VxIi+tOmpB\n"
+  "4ocnOLEcaxX12BzprW55ytfOCVpF1jHD/imAhb3YrHXu0fwe6DXYXfZV4SSG2vB7\n"
+  "IB9z14KBN5qLHjNGFpMQXHSMek+b/ftTU0ZnPh9uEM5D3YqRLVd7GcdUhHvG8P8Q\n"
+  "C9aXAoGBAJtID6h8wOGMP0XYX5YYnhlC7dOLfk8UYrzlp3xhqVkzKthTQTj6wx9R\n"
+  "GtC4k7U1ki8oJsfcIlBNXd768fqDVWjYju5rzShMpo8OCTS6ipAblKjCxPPVhIpv\n"
+  "tWPlbSn1qj6wylstJ5/3Z+ZW5H4wIKp5jmLiioDhcP0L/Ex3Zx8O\n"
+  "-----END RSA PRIVATE KEY-----\n";
+
+/* test server self signed certificates */
+const char srv_self_signed_cert_pem[] = "-----BEGIN CERTIFICATE-----\n"
+  "MIIC+jCCAeSgAwIBAgIES0KCvTALBgkqhkiG9w0BAQUwFzEVMBMGA1UEAxMMdGVz\n"
+  "dF9jYV9jZXJ0MB4XDTEwMDEwNTAwMDcyNVoXDTQ1MDMxMjAwMDcyNVowFzEVMBMG\n"
+  "A1UEAxMMdGVzdF9jYV9jZXJ0MIIBHzALBgkqhkiG9w0BAQEDggEOADCCAQkCggEA\n"
+  "tDEagv3p9OUhUL55jMucxjNK9N5cuozhcnrwDfBSU6oVrqm5kPqO1I7Cggzw68Y5\n"
+  "jhTcBi4FXmYOZppm1R3MhSJ5JSi/67Q7X4J5rnJLXYGN27qjMpnoGQ/2xmsNG/is\n"
+  "i+h/2vbtPU+WP9SEJnTfPLLpZ7KqCAk7FUUzKsuLx3/SOKtdkrWxPKwYTgnDEN6D\n"
+  "JL7tEzCnG5DFc4mQ7YW9PaRdC3rS1T8PvQ3jB2BUnohM0cFvKRuiU35tU7h7CPbL\n"
+  "4L66VglXoiwqmgcrwI2U968bD0+wRQ5c5bzNoshJOzN6CTMh1IhbklSh/Z6FA/e8\n"
+  "hj0yVo2tdllXuJGVs3PIEwIDAQABo1UwUzAMBgNVHRMBAf8EAjAAMBMGA1UdJQQM\n"
+  "MAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMHIAAwHQYDVR0OBBYEFDfU7pAv9LYn\n"
+  "n7jb4WHl4+Vgi2FnMAsGCSqGSIb3DQEBBQOCAQEAkaembPQMmv6OOjbIod8zTatr\n"
+  "x5Bwkwp3TOE1NRyy2OytzFIYRUkNrZYlcmrxcbNNycIK41CNVXbriFCF8gcmIq9y\n"
+  "vaKZn8Gcy+vGggv+1BP9IAPBGKRwSi0wmq9JoGE8hx+qqTpRSdfbM/cps/09hicO\n"
+  "0EIR7kWEbvnpMBcMKYOtYE9Gce7rdSMWVAsKc174xn8vW6TxCUvmWFv5DPg5HG1v\n"
+  "y1SUX73qafRo+W6FN4UC/DHfwRhF8RSKEnVbmgDVCs6GHdKBjU2qRgYyj6nWZqK1\n"
+  "XFUTWgia+Fl3D9vlsXaFcSZKA0Bq1eojl0B0AfeYAxTFwPWXscKvt/bXZfH8bg==\n"
+  "-----END CERTIFICATE-----\n";
+
+/* test server key */
+const char srv_key_pem[] = "-----BEGIN RSA PRIVATE KEY-----\n"
+  "MIIEpAIBAAKCAQEAtDEagv3p9OUhUL55jMucxjNK9N5cuozhcnrwDfBSU6oVrqm5\n"
+  "kPqO1I7Cggzw68Y5jhTcBi4FXmYOZppm1R3MhSJ5JSi/67Q7X4J5rnJLXYGN27qj\n"
+  "MpnoGQ/2xmsNG/isi+h/2vbtPU+WP9SEJnTfPLLpZ7KqCAk7FUUzKsuLx3/SOKtd\n"
+  "krWxPKwYTgnDEN6DJL7tEzCnG5DFc4mQ7YW9PaRdC3rS1T8PvQ3jB2BUnohM0cFv\n"
+  "KRuiU35tU7h7CPbL4L66VglXoiwqmgcrwI2U968bD0+wRQ5c5bzNoshJOzN6CTMh\n"
+  "1IhbklSh/Z6FA/e8hj0yVo2tdllXuJGVs3PIEwIDAQABAoIBAAEtcg+LFLGtoxjq\n"
+  "b+tFttBJfbRcfdG6ocYqBGmUXF+MgFs573DHX3sHNOQxlaNHtSgIclF1eYgNZFFt\n"
+  "VLIoBFTzfEQXoFosPUDoEuqVMeXLttmD7P2jwL780XJLZ4Xj6GY07npq1iGBcEZf\n"
+  "yCcdoyGkr9jgc5Auyis8DStGg/jfUBC4NBvF0GnuuNPAdYRPKUpKw9EatI+FdMjy\n"
+  "BuroD90fhdkK8EwMEVb9P17bdIc1MCIZFpUE9YHjVdK/oxCUhQ8KRfdbI4JU5Zh3\n"
+  "UtO6Jm2wFuP3VmeVpPvE/C2rxI70pyl6HMSiFGNc0rhJYCQ+yhohWj7nZ67H4vLx\n"
+  "plv5LxkCgYEAz7ewou8oFafDAMNoxaqKudvUg+lxXewdLDKaYBF5ACi9uAPCJ+v7\n"
+  "M5c/fvPFn/XHzo7xaXbtTAH3Z5xzBs+80OsvL+e1Ut4xR+ELRkybknh/s2wQeABk\n"
+  "Kb0vA59ukQGj12LV5phZMaVoXe6KJ7hZnN62d3K6m1wGE/k58i4pPLUCgYEA3hN8\n"
+  "G95zW7g0jVdSr+KUeVmephph9yh8Yb+3I3ojwOIv6d45TopGx8pFZlnBAMZf1ZQx\n"
+  "DIhzJNnaqZy/4w7RNaOGWnPA/5f+MIoHBiLGEEmfHC3lt087Yp9OuwDUHwpETYdV\n"
+  "o+KBCvVh60Et3bZUgF/1k/3YXxn8J5dsmJsjNqcCgYBLflyRa1BrRnTGMz9CEDCp\n"
+  "Si9b3h1Y4Hbd2GppHhCXMTd6yMrpDYhYANGQB3M9Juv+s88j4JhwNoq/uonH4Pqk\n"
+  "B8Y3qAQr4RuSH0WkwDUOsALhqBX4N1QwI1USAQEDbNAqeP5698X7GD3tXcQSmZrg\n"
+  "O8WfdjBCRNjkq4EW9xX/vQKBgQDONtmwJ0iHiu2BseyeVo/4fzfKlgUSNQ4K1rOA\n"
+  "xhIdMeu8Bxa/z7caHsGC4SVPSuYCtbE2Kh6BwapChcPJXCD45fgEViiJLuJiwEj1\n"
+  "caTpyvNsf1IoffJvCe9ZxtMyX549P8ZOgC3Dt0hN5CBrGLwu2Ox5l+YrqT10pi+5\n"
+  "JZX1UQKBgQCrcXrdkkDAc/a4+PxNRpJRLcU4fhv8/lr+UWItE8eUe7bd25bTQfQm\n"
+  "VpNKc/kAJ66PjIED6fy3ADhd2y4naT2a24uAgQ/M494J68qLnGh6K4JU/09uxR2v\n"
+  "1i2q/4FNLdFFk1XP4iNnTHRLZ+NYr2p5Y9RcvQfTjOauz8Ahav0lyg==\n"
+  "-----END RSA PRIVATE KEY-----\n";
+
+#endif
diff --git a/src/testcurl/perf_get.c b/src/testcurl/perf_get.c
new file mode 100644
index 0000000..1e42f7d
--- /dev/null
+++ b/src/testcurl/perf_get.c
@@ -0,0 +1,532 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007, 2009, 2011 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file perf_get.c
+ * @brief benchmark simple GET operations (sequential access).
+ *        Note that we run libcurl in the same process at the
+ *        same time, so the execution time given is the combined
+ *        time for both MHD and libcurl; it is quite possible
+ *        that more time is spend with libcurl than with MHD,
+ *        so the performance scores calculated with this code
+ *        should NOT be used to compare with other HTTP servers
+ *        (since MHD is actually better); only the relative
+ *        scores between MHD versions are meaningful.  
+ *        Furthermore, this code ONLY tests MHD processing
+ *        a single request at a time.  This is again
+ *        not universally meaningful (i.e. when comparing
+ *        multithreaded vs. single-threaded or select/poll).
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "gauger.h"
+
+#ifndef WINDOWS
+#include <unistd.h>
+#include <sys/socket.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+/**
+ * How many rounds of operations do we do for each
+ * test?
+ */
+#define ROUNDS 500
+
+/**
+ * Do we use HTTP 1.1?
+ */
+static int oneone;
+
+/**
+ * Response to return (re-used).
+ */
+static struct MHD_Response *response;
+
+/**
+ * Time this round was started.
+ */
+static unsigned long long start_time;
+
+
+/**
+ * Get the current timestamp 
+ *
+ * @return current time in ms
+ */
+static unsigned long long 
+now ()
+{
+  struct timeval tv;
+
+  gettimeofday (&tv, NULL);
+  return (((unsigned long long) tv.tv_sec * 1000LL) +
+	  ((unsigned long long) tv.tv_usec / 1000LL));
+}
+
+
+/**
+ * Start the timer.
+ */
+static void 
+start_timer()
+{
+  start_time = now ();
+}
+
+
+/**
+ * Stop the timer and report performance
+ *
+ * @param desc description of the threading mode we used
+ */
+static void 
+stop (const char *desc)
+{
+  double rps = ((double) (ROUNDS * 1000)) / ((double) (now() - start_time));
+
+  fprintf (stderr,
+	   "Sequential GETs using %s: %f %s\n",
+	   desc,
+	   rps,
+	   "requests/s");
+  GAUGER (desc,
+	  "Sequential GETs",
+	  rps,
+	  "requests/s");
+}
+
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+
+static size_t
+copyBuffer (void *ptr, 
+	    size_t size, size_t nmemb, 
+	    void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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;
+  const char *me = cls;
+  int ret;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+static int
+testInternalGet (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];
+
+  sprintf(url, "http://127.0.0.1:%d/hello_world", port);
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG  | poll_flag,
+                        port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  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, 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 2;
+	}
+      curl_easy_cleanup (c);
+    }
+  stop (poll_flag == MHD_USE_POLL ? "internal poll" :
+	poll_flag == MHD_USE_EPOLL_LINUX_ONLY ? "internal epoll" : "internal select");
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    return 4;
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 8;
+  return 0;
+}
+
+
+static int
+testMultithreadedGet (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];
+
+  sprintf(url, "http://127.0.0.1:%d/hello_world", port);
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG  | poll_flag,
+                        port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  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, 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, 150L);
+      /* 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 32;
+	}
+      curl_easy_cleanup (c);
+    }
+  stop ((poll_flag & MHD_USE_POLL) ? "thread with poll" :
+	(poll_flag & MHD_USE_EPOLL_LINUX_ONLY) ? "thread with epoll" : "thread 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
+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];
+
+  sprintf(url, "http://127.0.0.1:%d/hello_world", port);
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag,
+                        port, NULL, NULL, &ahc_echo, "GET",
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  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, 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, 150L);
+      /* 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 32;
+	}
+      curl_easy_cleanup (c);
+    }
+  stop (0 != (poll_flag & MHD_USE_POLL) ? "thread pool with poll" : 
+	0 != (poll_flag & MHD_USE_EPOLL_LINUX_ONLY) ? "thread pool with epoll" : "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
+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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+  unsigned int i;
+  char url[64];
+
+  sprintf(url, "http://127.0.0.1:%d/hello_world", port);
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  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, 1);
+      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, 1);
+      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))
+	{
+	  max = 0;
+	  FD_ZERO (&rs);
+	  FD_ZERO (&ws);
+	  FD_ZERO (&es);
+	  curl_multi_perform (multi, &running);
+	  mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+	  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, &max))
+	    {
+	      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;
+	  select (max + 1, &rs, &ws, &es, &tv);
+	  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;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+  int port = 1081;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  response = MHD_create_response_from_buffer (strlen ("/hello_world"),
+					      "/hello_world",
+					      MHD_RESPMEM_MUST_COPY);
+  errorCount += testExternalGet (port++);
+  errorCount += testInternalGet (port++, 0);
+  errorCount += testMultithreadedGet (port++, 0);
+  errorCount += testMultithreadedPoolGet (port++, 0);
+  if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
+    {
+      errorCount += testInternalGet(port++, MHD_USE_POLL);
+      errorCount += testMultithreadedGet(port++, MHD_USE_POLL);
+      errorCount += testMultithreadedPoolGet(port++, MHD_USE_POLL);
+    }
+  if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
+    {
+      errorCount += testInternalGet(port++, MHD_USE_EPOLL_LINUX_ONLY);
+      errorCount += testMultithreadedPoolGet(port++, MHD_USE_EPOLL_LINUX_ONLY);
+    }
+  MHD_destroy_response (response);
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/perf_get_concurrent.c b/src/testcurl/perf_get_concurrent.c
new file mode 100644
index 0000000..28559ee
--- /dev/null
+++ b/src/testcurl/perf_get_concurrent.c
@@ -0,0 +1,364 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007, 2009, 2011 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file perf_get_concurrent.c
+ * @brief benchmark concurrent GET operations
+ *        Note that we run libcurl on the machine at the
+ *        same time, so the execution time may be influenced
+ *        by the concurrent activity; it is quite possible
+ *        that more time is spend with libcurl than with MHD,
+ *        so the performance scores calculated with this code
+ *        should NOT be used to compare with other HTTP servers
+ *        (since MHD is actually better); only the relative
+ *        scores between MHD versions are meaningful.  
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "gauger.h"
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+/**
+ * How many rounds of operations do we do for each
+ * test (total number of requests will be ROUNDS * PAR).
+ */
+#define ROUNDS 500
+
+/**
+ * How many requests do we do in parallel?
+ */
+#define PAR CPU_COUNT
+
+/**
+ * Do we use HTTP 1.1?
+ */
+static int oneone;
+
+/**
+ * Response to return (re-used).
+ */
+static struct MHD_Response *response;
+
+/**
+ * Time this round was started.
+ */
+static unsigned long long start_time;
+
+
+/**
+ * Get the current timestamp 
+ *
+ * @return current time in ms
+ */
+static unsigned long long 
+now ()
+{
+  struct timeval tv;
+
+  gettimeofday (&tv, NULL);
+  return (((unsigned long long) tv.tv_sec * 1000LL) +
+	  ((unsigned long long) tv.tv_usec / 1000LL));
+}
+
+
+/**
+ * Start the timer.
+ */
+static void 
+start_timer()
+{
+  start_time = now ();
+}
+
+
+/**
+ * Stop the timer and report performance
+ *
+ * @param desc description of the threading mode we used
+ */
+static void 
+stop (const char *desc)
+{
+  double rps = ((double) (PAR * ROUNDS * 1000)) / ((double) (now() - start_time));
+
+  fprintf (stderr,
+	   "Parallel GETs using %s: %f %s\n",
+	   desc,
+	   rps,
+	   "requests/s");
+  GAUGER (desc,
+	  "Parallel GETs",
+	  rps,
+	  "requests/s");
+}
+
+
+static size_t
+copyBuffer (void *ptr, 
+	    size_t size, size_t nmemb, 
+	    void *ctx)
+{
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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;
+  const char *me = cls;
+  int ret;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+static pid_t
+do_gets (int port)
+{
+  pid_t ret;
+  CURL *c;
+  CURLcode errornum;
+  unsigned int i;
+  unsigned int j;
+  pid_t par[PAR];
+  char url[64];
+
+  sprintf(url, "http://127.0.0.1:%d/hello_world", port);
+  
+  ret = fork ();
+  if (ret == -1) abort ();
+  if (ret != 0)
+    return ret;
+  for (j=0;j<PAR;j++)
+    {
+      par[j] = fork ();
+      if (par[j] == 0)
+	{
+	  for (i=0;i<ROUNDS;i++)
+	    {
+	      c = curl_easy_init ();
+	      curl_easy_setopt (c, CURLOPT_URL, url);
+	      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+	      curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL);
+	      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, 150L);
+	      /* 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);
+		  _exit (1);
+		}
+	      curl_easy_cleanup (c);
+	    }
+	  _exit (0);
+	}
+    }
+  for (j=0;j<PAR;j++)
+    waitpid (par[j], NULL, 0);
+  _exit (0);
+}
+
+
+static void 
+join_gets (pid_t pid)
+{
+  int status;
+  
+  status = 1;
+  waitpid (pid, &status, 0);
+  if (0 != status)
+    abort ();
+}
+
+
+static int
+testInternalGet (int port, int poll_flag)
+{
+  struct MHD_Daemon *d;
+
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG  | poll_flag,
+                        port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  start_timer ();
+  join_gets (do_gets (port));
+  stop (poll_flag ? "internal poll" : "internal select");
+  MHD_stop_daemon (d);
+  return 0;
+}
+
+
+static int
+testMultithreadedGet (int port, int poll_flag)
+{
+  struct MHD_Daemon *d;
+
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG  | poll_flag,
+                        port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  start_timer ();
+  join_gets (do_gets (port));
+  stop (poll_flag ? "thread with poll" : "thread with select");
+  MHD_stop_daemon (d);
+  return 0;
+}
+
+static int
+testMultithreadedPoolGet (int port, int poll_flag)
+{
+  struct MHD_Daemon *d;
+
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag,
+                        port, NULL, NULL, &ahc_echo, "GET",
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  start_timer ();
+  join_gets (do_gets (port));
+  stop (poll_flag ? "thread pool with poll" : "thread pool with select");
+  MHD_stop_daemon (d);
+  return 0;
+}
+
+static int
+testExternalGet (int port)
+{
+  struct MHD_Daemon *d;
+  pid_t pid;
+  fd_set rs;
+  fd_set ws;
+  fd_set es;
+  MHD_socket max;
+  struct timeval tv;
+  MHD_UNSIGNED_LONG_LONG tt;
+  int tret;
+
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  start_timer ();
+  pid = do_gets (port);
+  while (0 == waitpid (pid, NULL, WNOHANG))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+	{
+	  MHD_stop_daemon (d);
+	  return 4096;
+	}
+      tret = MHD_get_timeout (d, &tt);
+      if (MHD_YES != tret) tt = 1;
+      tv.tv_sec = tt / 1000;
+      tv.tv_usec = 1000 * (tt % 1000);
+      if (-1 == select (max + 1, &rs, &ws, &es, &tv))
+	{
+	  if (EINTR == errno)
+	    continue;
+	  fprintf (stderr,
+		   "select failed: %s\n",
+		   strerror (errno));
+	  break;	      	  
+	}
+      MHD_run (d);
+    }
+  stop ("external select");
+  MHD_stop_daemon (d);
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+  int port = 1081;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  response = MHD_create_response_from_buffer (strlen ("/hello_world"),
+					      "/hello_world",
+					      MHD_RESPMEM_MUST_COPY);
+  errorCount += testInternalGet (port++, 0);
+  errorCount += testMultithreadedGet (port++, 0);
+  errorCount += testMultithreadedPoolGet (port++, 0);
+  errorCount += testExternalGet (port++);
+#ifndef WINDOWS
+  errorCount += testInternalGet (port++, MHD_USE_POLL);
+  errorCount += testMultithreadedGet (port++, MHD_USE_POLL);
+  errorCount += testMultithreadedPoolGet (port++, MHD_USE_POLL);
+#endif
+#if EPOLL_SUPPORT
+  errorCount += testInternalGet (port++, MHD_USE_EPOLL_LINUX_ONLY);
+  errorCount += testMultithreadedPoolGet (port++, MHD_USE_EPOLL_LINUX_ONLY);
+#endif
+  MHD_destroy_response (response);
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_callback.c b/src/testcurl/test_callback.c
new file mode 100644
index 0000000..83233e6
--- /dev/null
+++ b/src/testcurl/test_callback.c
@@ -0,0 +1,189 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007, 2009, 2011 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_callback.c
+ * @brief Testcase for MHD not calling the callback too often
+ * @author Jan Seeger 
+ * @author Christian Grothoff
+ */
+
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+
+struct callback_closure {
+  unsigned int called;
+};
+
+
+static ssize_t 
+called_twice(void *cls, uint64_t pos, char *buf, size_t max) 
+{
+  struct callback_closure *cls2 = cls;
+  
+  if (cls2->called == 0) 
+    {
+      memset(buf, 0, max);
+      strcat(buf, "test");
+      cls2->called = 1;
+      return strlen(buf);
+    }
+  if (cls2->called == 1) 
+    {
+      cls2->called = 2;
+      return MHD_CONTENT_READER_END_OF_STREAM;
+    }
+  fprintf(stderr, 
+	  "Handler called after returning END_OF_STREAM!\n");
+  return MHD_CONTENT_READER_END_WITH_ERROR;
+}
+
+
+static int
+callback(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 **con_cls) {
+  struct callback_closure *cbc = calloc(1, sizeof(struct callback_closure));
+  struct MHD_Response *r;
+
+  r = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 1024, 
+					 &called_twice, cbc, 
+					 &free);
+  MHD_queue_response(connection, 200, r);
+  MHD_destroy_response(r);
+  return MHD_YES;
+}
+
+
+static size_t
+discard_buffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  return size * nmemb;
+}
+
+
+int main(int argc, char **argv) 
+{
+  struct MHD_Daemon *d;
+  fd_set rs;
+  fd_set ws;
+  fd_set es;
+  MHD_socket max;
+  CURL *c;
+  CURLM *multi;
+  CURLMcode mret;
+  struct CURLMsg *msg;
+  int running;
+  struct timeval tv;
+  int extra;
+
+  d = MHD_start_daemon(0, 
+		       8000,
+		       NULL,
+		       NULL,
+		       callback,
+		       NULL,
+		       MHD_OPTION_END);
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:8000/");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &discard_buffer);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  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);
+  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+  multi = curl_multi_init ();
+  if (multi == NULL)
+    {
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      return 1;
+    }
+  mret = curl_multi_add_handle (multi, c);
+  if (mret != CURLM_OK)
+    {
+      curl_multi_cleanup (multi);
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      return 2;
+    }
+  extra = 10;
+  while ( (c != NULL) || (--extra > 0) )
+    {
+      max = MHD_INVALID_SOCKET;
+      FD_ZERO(&ws);
+      FD_ZERO(&rs);
+      FD_ZERO(&es);
+      curl_multi_perform (multi, &running);
+      if (NULL != multi)
+	{
+	  mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+	  if (mret != CURLM_OK)
+	    {
+	      curl_multi_remove_handle (multi, c);
+	      curl_multi_cleanup (multi);
+	      curl_easy_cleanup (c);
+	      MHD_stop_daemon (d);
+	      return 3;
+	    }   
+	}
+      if (MHD_YES !=
+	  MHD_get_fdset(d, &rs, &ws, &es, &max))
+	{
+          curl_multi_remove_handle (multi, c);
+          curl_multi_cleanup (multi);
+          curl_easy_cleanup (c);
+          MHD_stop_daemon (d);
+	  return 4;
+	}
+      tv.tv_sec = 0;
+      tv.tv_usec = 1000;
+      select(max + 1, &rs, &ws, &es, &tv);
+      if (NULL != multi)
+	{
+	  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);
+    }
+  MHD_stop_daemon(d);
+  return 0;
+}
diff --git a/src/testcurl/test_concurrent_stop.c b/src/testcurl/test_concurrent_stop.c
new file mode 100644
index 0000000..60cc98d
--- /dev/null
+++ b/src/testcurl/test_concurrent_stop.c
@@ -0,0 +1,228 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007, 2009, 2011, 2015 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_concurrent_stop.c
+ * @brief test stopping server while concurrent GETs are ongoing
+ * @author Christian Grothoff
+ */
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "gauger.h"
+
+#ifdef CPU_COUNT
+#undef CPU_COUNT
+#endif
+#define CPU_COUNT 40
+
+
+/**
+ * How many rounds of operations do we do for each
+ * test (total number of requests will be ROUNDS * PAR).
+ */
+#define ROUNDS 50000
+
+/**
+ * How many requests do we do in parallel?
+ */
+#define PAR CPU_COUNT
+
+/**
+ * Do we use HTTP 1.1?
+ */
+static int oneone;
+
+/**
+ * Response to return (re-used).
+ */
+static struct MHD_Response *response;
+
+
+static size_t
+copyBuffer (void *ptr,
+	    size_t size, size_t nmemb,
+	    void *ctx)
+{
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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;
+  const char *me = cls;
+  int ret;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  ret = MHD_queue_response (connection,
+                            MHD_HTTP_OK,
+                            response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+static pid_t
+do_gets (int port)
+{
+  pid_t ret;
+  CURL *c;
+  CURLcode errornum;
+  unsigned int i;
+  unsigned int j;
+  pid_t par[PAR];
+  char url[64];
+
+  sprintf(url, "http://127.0.0.1:%d/hello_world", port);
+
+  ret = fork ();
+  if (ret == -1) abort ();
+  if (ret != 0)
+    return ret;
+  for (j=0;j<PAR;j++)
+    {
+      par[j] = fork ();
+      if (par[j] == 0)
+	{
+	  for (i=0;i<ROUNDS;i++)
+	    {
+	      c = curl_easy_init ();
+	      curl_easy_setopt (c, CURLOPT_URL, url);
+	      curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+	      curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL);
+	      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, 150L);
+	      /* 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)))
+		{
+		  curl_easy_cleanup (c);
+		  _exit (1);
+		}
+	      curl_easy_cleanup (c);
+	    }
+	  _exit (0);
+	}
+    }
+  for (j=0;j<PAR;j++)
+    waitpid (par[j], NULL, 0);
+  _exit (0);
+}
+
+
+static void
+join_gets (pid_t pid)
+{
+  int status;
+
+  status = 1;
+  waitpid (pid, &status, 0);
+  if (0 != status)
+    abort ();
+}
+
+
+static int
+testMultithreadedGet (int port, int poll_flag)
+{
+  struct MHD_Daemon *d;
+  pid_t p;
+
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG  | poll_flag,
+                        port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  p = do_gets (port);
+  sleep (1);
+  MHD_stop_daemon (d);
+  join_gets (p);
+  return 0;
+}
+
+
+static int
+testMultithreadedPoolGet (int port, int poll_flag)
+{
+  struct MHD_Daemon *d;
+  pid_t p;
+
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag,
+                        port,
+                        NULL, NULL,
+                        &ahc_echo, "GET",
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT,
+                        MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  p = do_gets (port);
+  sleep (1);
+  MHD_stop_daemon (d);
+  join_gets (p);
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+  int port = 1081;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  response = MHD_create_response_from_buffer (strlen ("/hello_world"),
+					      "/hello_world",
+					      MHD_RESPMEM_MUST_COPY);
+  errorCount += testMultithreadedGet (port++, 0);
+  errorCount += testMultithreadedPoolGet (port++, 0);
+  MHD_destroy_response (response);
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_digestauth.c b/src/testcurl/test_digestauth.c
new file mode 100644
index 0000000..255e086
--- /dev/null
+++ b/src/testcurl/test_digestauth.c
@@ -0,0 +1,247 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2010 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file daemontest_digestauth.c
+ * @brief  Testcase for libmicrohttpd Digest Auth
+ * @author Amr Ali
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_GCRYPT_H
+#include <gcrypt.h>
+#endif
+
+#ifndef WINDOWS
+#include <sys/socket.h>
+#include <unistd.h>
+#else
+#include <wincrypt.h>
+#endif
+
+#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
+
+#define DENIED "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
+
+#define MY_OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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;
+  char *username;
+  const char *password = "testpass";
+  const char *realm = "test@example.com";
+  int ret;
+
+  username = MHD_digest_auth_get_username(connection);
+  if ( (username == NULL) ||
+       (0 != strcmp (username, "testuser")) )
+    {
+      response = MHD_create_response_from_buffer(strlen (DENIED), 
+						 DENIED,
+						 MHD_RESPMEM_PERSISTENT);  
+      ret = MHD_queue_auth_fail_response(connection, realm,
+					 MY_OPAQUE,
+					 response,
+					 MHD_NO);    
+      MHD_destroy_response(response);  
+      return ret;
+    }
+  ret = MHD_digest_auth_check(connection, realm,
+			      username, 
+			      password, 
+			      300);
+  free(username);
+  if ( (ret == MHD_INVALID_NONCE) ||
+       (ret == MHD_NO) )
+    {
+      response = MHD_create_response_from_buffer(strlen (DENIED), 
+						 DENIED,
+						 MHD_RESPMEM_PERSISTENT);  
+      if (NULL == response) 
+	return MHD_NO;
+      ret = MHD_queue_auth_fail_response(connection, realm,
+					 MY_OPAQUE,
+					 response,
+					 (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);  
+      MHD_destroy_response(response);  
+      return ret;
+    }
+  response = MHD_create_response_from_buffer(strlen(PAGE), PAGE,
+					     MHD_RESPMEM_PERSISTENT);
+  ret = MHD_queue_response(connection, MHD_HTTP_OK, response);  
+  MHD_destroy_response(response);
+  return ret;
+}
+
+
+static int
+testDigestAuth ()
+{
+  int fd;
+  CURL *c;
+  CURLcode errornum;
+  struct MHD_Daemon *d;
+  struct CBC cbc;
+  size_t len;
+  size_t off = 0;
+  char buf[2048];
+  char rnd[8];
+
+  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 == -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, 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_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1337, 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;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1337/");
+  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, 1);
+  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, 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 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;
+}
+
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+#ifdef HAVE_GCRYPT_H
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+#endif
+if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testDigestAuth ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_digestauth_with_arguments.c b/src/testcurl/test_digestauth_with_arguments.c
new file mode 100644
index 0000000..51868ab
--- /dev/null
+++ b/src/testcurl/test_digestauth_with_arguments.c
@@ -0,0 +1,245 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2010, 2012 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file daemontest_digestauth_with_arguments.c
+ * @brief  Testcase for libmicrohttpd Digest Auth with arguments
+ * @author Amr Ali
+ */
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_GCRYPT_H
+#include <gcrypt.h>
+#endif
+
+#ifndef WINDOWS
+#include <sys/socket.h>
+#include <unistd.h>
+#else
+#include <wincrypt.h>
+#endif
+
+#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
+
+#define DENIED "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
+
+#define MY_OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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;
+  char *username;
+  const char *password = "testpass";
+  const char *realm = "test@example.com";
+  int ret;
+
+  username = MHD_digest_auth_get_username(connection);
+  if ( (username == NULL) ||
+       (0 != strcmp (username, "testuser")) )
+    {
+      response = MHD_create_response_from_buffer(strlen (DENIED), 
+						 DENIED,
+						 MHD_RESPMEM_PERSISTENT);  
+      ret = MHD_queue_auth_fail_response(connection, realm,
+					 MY_OPAQUE,
+					 response,
+					 MHD_NO);    
+      MHD_destroy_response(response);  
+      return ret;
+    }
+  ret = MHD_digest_auth_check(connection, realm,
+			      username, 
+			      password, 
+			      300);
+  free(username);
+  if ( (ret == MHD_INVALID_NONCE) ||
+       (ret == MHD_NO) )
+    {
+      response = MHD_create_response_from_buffer(strlen (DENIED), 
+						 DENIED,
+						 MHD_RESPMEM_PERSISTENT);  
+      if (NULL == response) 
+	return MHD_NO;
+      ret = MHD_queue_auth_fail_response(connection, realm,
+					 MY_OPAQUE,
+					 response,
+					 (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);  
+      MHD_destroy_response(response);  
+      return ret;
+    }
+  response = MHD_create_response_from_buffer(strlen(PAGE), PAGE,
+					     MHD_RESPMEM_PERSISTENT);
+  ret = MHD_queue_response(connection, MHD_HTTP_OK, response);  
+  MHD_destroy_response(response);
+  return ret;
+}
+
+
+static int
+testDigestAuth ()
+{
+  int fd;
+  CURL *c;
+  CURLcode errornum;
+  struct MHD_Daemon *d;
+  struct CBC cbc;
+  size_t len;
+  size_t off = 0;
+  char buf[2048];
+  char rnd[8];
+
+  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 == -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, 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_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1337, 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;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1337/foo?key=value");
+  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, 1);
+  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, 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 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;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+#ifdef HAVE_GCRYPT_H
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+#endif
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testDigestAuth ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_get.c b/src/testcurl/test_get.c
new file mode 100644
index 0000000..e4c531d
--- /dev/null
+++ b/src/testcurl/test_get.c
@@ -0,0 +1,640 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007, 2009, 2011 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_get.c
+ * @brief  Testcase for libmicrohttpd GET operations
+ *         TODO: test parsing of query
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include "platform_interface.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif /* !WIN32_LEAN_AND_MEAN */
+#include <windows.h>
+#endif
+
+#ifndef WINDOWS
+#include <unistd.h>
+#include <sys/socket.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+static int oneone;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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;
+  const char *me = cls;
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  response = MHD_create_response_from_buffer (strlen (url),
+					      (void *) url,
+					      MHD_RESPMEM_MUST_COPY);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+static int
+testInternalGet (int poll_flag)
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG  | poll_flag,
+                        11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world");
+  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, 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 2;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    return 4;
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 8;
+  return 0;
+}
+
+
+static int
+testMultithreadedGet (int poll_flag)
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG  | poll_flag,
+                        1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  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);
+  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, 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 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;
+}
+
+
+static int
+testMultithreadedPoolGet (int poll_flag)
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag,
+                        1081, NULL, NULL, &ahc_echo, "GET",
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  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);
+  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, 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 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;
+}
+
+
+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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  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, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      curl_multi_perform (multi, &running);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      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, &max))
+        {
+          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;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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;
+}
+
+
+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, (struct sockaddr *) &addr, &addr_len))
+    return 131072;
+
+  if (addr.sin_family != AF_INET)
+    return 26214;
+
+  snprintf(buf, sizeof(buf), "http://127.0.0.1:%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, 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 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;
+}
+
+
+static int
+testStopRace (int poll_flag)
+{
+    struct sockaddr_in sin;
+    MHD_socket fd;
+    struct MHD_Daemon *d;
+
+    d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | poll_flag,
+                         1081, NULL, NULL, &ahc_echo, "GET",
+                         MHD_OPTION_CONNECTION_TIMEOUT, 5, MHD_OPTION_END);
+    if (d == NULL)
+       return 16;
+
+    fd = socket (PF_INET, SOCK_STREAM, 0);
+    if (fd == MHD_INVALID_SOCKET)
+    {
+       fprintf(stderr, "socket error\n");
+       return 256;
+    }
+
+    memset(&sin, 0, sizeof(sin));
+    sin.sin_family = AF_INET;
+    sin.sin_port = htons(1081);
+    sin.sin_addr.s_addr = htonl(0x7f000001);
+
+    if (connect (fd, (struct sockaddr *)(&sin), sizeof(sin)) < 0)
+    {
+       fprintf(stderr, "connect error\n");
+       MHD_socket_close_ (fd);
+       return 512;
+    }
+
+    /*  printf("Waiting\n"); */
+    /* Let the thread get going. */
+    usleep(500000);
+
+    /* printf("Stopping daemon\n"); */
+    MHD_stop_daemon (d);
+
+    MHD_socket_close_ (fd);
+
+    /* printf("good\n"); */
+    return 0;
+}
+
+
+static int
+ahc_empty (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;
+
+  if (0 != strcmp ("GET", method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  response = MHD_create_response_from_buffer (0,
+					      NULL,
+					      MHD_RESPMEM_PERSISTENT);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+static int
+curlExcessFound(CURL *c, curl_infotype type, char *data, size_t size, void *cls)
+{
+  static const char *excess_found = "Excess found";
+  const size_t str_size = strlen (excess_found);
+
+  if (CURLINFO_TEXT == type
+      && size >= str_size
+      && 0 == strncmp(excess_found, data, str_size))
+    *(int *)cls = 1;
+  return 0;
+}
+
+
+static int
+testEmptyGet (int poll_flag)
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+  int excess_found = 0;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG  | poll_flag,
+                        11081, NULL, NULL, &ahc_empty, NULL, MHD_OPTION_END);
+  if (d == NULL)
+    return 4194304;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+  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 8388608;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != 0)
+    return 16777216;
+  if (excess_found)
+    return 33554432;
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testInternalGet (0);
+  errorCount += testMultithreadedGet (0);
+  errorCount += testMultithreadedPoolGet (0);
+  errorCount += testUnknownPortGet (0);
+  errorCount += testStopRace (0);
+  errorCount += testExternalGet ();
+  errorCount += testEmptyGet (0);
+  if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
+    {
+      errorCount += testInternalGet(MHD_USE_POLL);
+      errorCount += testMultithreadedGet(MHD_USE_POLL);
+      errorCount += testMultithreadedPoolGet(MHD_USE_POLL);
+      errorCount += testUnknownPortGet(MHD_USE_POLL);
+      errorCount += testStopRace(MHD_USE_POLL);
+      errorCount += testEmptyGet(MHD_USE_POLL);
+    }
+  if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
+    {
+      errorCount += testInternalGet(MHD_USE_EPOLL_LINUX_ONLY);
+      errorCount += testMultithreadedPoolGet(MHD_USE_EPOLL_LINUX_ONLY);
+      errorCount += testUnknownPortGet(MHD_USE_EPOLL_LINUX_ONLY);
+      errorCount += testEmptyGet(MHD_USE_EPOLL_LINUX_ONLY);
+    }
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_get_chunked.c b/src/testcurl/test_get_chunked.c
new file mode 100644
index 0000000..3b8bf39
--- /dev/null
+++ b/src/testcurl/test_get_chunked.c
@@ -0,0 +1,414 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file daemontest_get_chunked.c
+ * @brief  Testcase for libmicrohttpd GET operations with chunked content encoding
+ *         TODO:
+ *         - how to test that chunking was actually used?
+ *         - use CURLOPT_HEADERFUNCTION to validate
+ *           footer was sent
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+/**
+ * MHD content reader callback that returns
+ * data in chunks.
+ */
+static ssize_t
+crc (void *cls, uint64_t pos, char *buf, size_t max)
+{
+  struct MHD_Response **responseptr = cls;
+
+  if (pos == 128 * 10)
+    {
+      MHD_add_response_header (*responseptr, "Footer", "working");
+      return MHD_CONTENT_READER_END_OF_STREAM;
+    }
+  if (max < 128)
+    abort ();                   /* should not happen in this testcase... */
+  memset (buf, 'A' + (pos / 128), 128);
+  return 128;
+}
+
+/**
+ * Dummy function that does nothing.
+ */
+static void
+crcf (void *ptr)
+{
+  free (ptr);
+}
+
+static int
+ahc_echo (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 **ptr)
+{
+  static int aptr;
+  const char *me = cls;
+  struct MHD_Response *response;
+  struct MHD_Response **responseptr;
+  int ret;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&aptr != *ptr)
+    {
+      /* do never respond on first call */
+      *ptr = &aptr;
+      return MHD_YES;
+    }
+  responseptr = malloc (sizeof (struct MHD_Response *));
+  if (responseptr == NULL)
+    return MHD_NO;
+  response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN,
+                                                1024,
+                                                &crc, responseptr, &crcf);
+  *responseptr = response;
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  return ret;
+}
+
+static int
+validate (struct CBC cbc, int ebase)
+{
+  int i;
+  char buf[128];
+
+  if (cbc.pos != 128 * 10)
+    return ebase;
+
+  for (i = 0; i < 10; i++)
+    {
+      memset (buf, 'A' + i, 128);
+      if (0 != memcmp (buf, &cbc.buf[i * 128], 128))
+        {
+          fprintf (stderr,
+                   "Got  `%.*s'\nWant `%.*s'\n",
+                   128, buf, 128, &cbc.buf[i * 128]);
+          return ebase * 2;
+        }
+    }
+  return 0;
+}
+
+static int
+testInternalGet ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+  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, 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, 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 2;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  return validate (cbc, 4);
+}
+
+static int
+testMultithreadedGet ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  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_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  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_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, 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 32;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  return validate (cbc, 64);
+}
+
+static int
+testMultithreadedPoolGet ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1081, NULL, NULL, &ahc_echo, "GET",
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  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_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, 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 32;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  return validate (cbc, 64);
+}
+
+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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+  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_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L);
+  // NOTE: use of CONNECTTIMEOUT without also
+  //   setting NOSIGNAL results in really weird
+  //   crashes on my system!
+  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      curl_multi_perform (multi, &running);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      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, &max))
+        {
+          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;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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);
+  return validate (cbc, 8192);
+}
+
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testInternalGet ();
+  errorCount += testMultithreadedGet ();
+  errorCount += testMultithreadedPoolGet ();
+  errorCount += testExternalGet ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_get_response_cleanup.c b/src/testcurl/test_get_response_cleanup.c
new file mode 100644
index 0000000..f881746
--- /dev/null
+++ b/src/testcurl/test_get_response_cleanup.c
@@ -0,0 +1,302 @@
+/* DO NOT CHANGE THIS LINE */
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007, 2009 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file daemontest_get_response_cleanup.c
+ * @brief  Testcase for libmicrohttpd response cleanup
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+
+#ifndef WINDOWS
+#include <sys/socket.h>
+#include <unistd.h>
+#endif
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif /* !WIN32_LEAN_AND_MEAN */
+#include <windows.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+#define TESTSTR "/* DO NOT CHANGE THIS LINE */"
+
+static int oneone;
+
+static int ok;
+
+
+static pid_t
+fork_curl (const char *url)
+{
+  pid_t ret;
+
+  ret = fork();
+  if (ret != 0)
+    return ret;
+  execlp ("curl", "curl", "-s", "-N", "-o", "/dev/null", "-GET", url, NULL);
+  fprintf (stderr, 
+	   "Failed to exec curl: %s\n",
+	   strerror (errno));
+  _exit (-1);  
+}
+
+static void
+kill_curl (pid_t pid)
+{
+  int status;
+
+  //fprintf (stderr, "Killing curl\n");
+  kill (pid, SIGTERM);
+  waitpid (pid, &status, 0);
+}
+
+
+static ssize_t
+push_callback (void *cls, uint64_t pos, char *buf, size_t max)
+{
+  if (max == 0)
+    return 0;
+  buf[0] = 'd';
+  return 1;
+}
+
+static void
+push_free_callback (void *cls)
+{
+  int *ok = cls;
+
+  //fprintf (stderr, "Cleanup callback called!\n");
+  *ok = 0;
+}
+
+
+static int
+ahc_echo (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;
+  const char *me = cls;
+  struct MHD_Response *response;
+  int ret;
+
+  //fprintf (stderr, "In CB: %s!\n", method);
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 
+						32 * 1024,
+						&push_callback,
+						&ok,
+						&push_free_callback);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+static int
+testInternalGet ()
+{
+  struct MHD_Daemon *d;
+  pid_t curl;
+
+  ok = 1;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  curl = fork_curl ("http://127.0.0.1:11080/");
+  sleep (1);
+  kill_curl (curl);
+  sleep (1);
+  // fprintf (stderr, "Stopping daemon!\n");
+  MHD_stop_daemon (d);
+  if (ok != 0)
+    return 2;
+  return 0;
+}
+
+static int
+testMultithreadedGet ()
+{
+  struct MHD_Daemon *d;
+  pid_t curl;
+
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
+                        1081, NULL, NULL, &ahc_echo, "GET",
+			MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 2,
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  ok = 1;
+  //fprintf (stderr, "Forking cURL!\n");
+  curl = fork_curl ("http://127.0.0.1:1081/");
+  sleep (1);
+  kill_curl (curl);
+  sleep (1);
+  curl = fork_curl ("http://127.0.0.1:1081/");
+  sleep (1);
+  if (ok != 0)
+    {
+      kill_curl (curl);
+      MHD_stop_daemon (d);
+      return 64;
+    }
+  kill_curl (curl);
+  sleep (1);
+  //fprintf (stderr, "Stopping daemon!\n");
+  MHD_stop_daemon (d);
+  if (ok != 0)
+    return 32;
+
+  return 0;
+}
+
+static int
+testMultithreadedPoolGet ()
+{
+  struct MHD_Daemon *d;
+  pid_t curl;
+
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1081, NULL, NULL, &ahc_echo, "GET",
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+  if (d == NULL)
+    return 64;
+  ok = 1;
+  curl = fork_curl ("http://127.0.0.1:1081/");
+  sleep (1);
+  kill_curl (curl);
+  sleep (1);
+  //fprintf (stderr, "Stopping daemon!\n");
+  MHD_stop_daemon (d);
+  if (ok != 0)
+    return 128;
+  return 0;
+}
+
+static int
+testExternalGet ()
+{
+  struct MHD_Daemon *d;
+  fd_set rs;
+  fd_set ws;
+  fd_set es;
+  MHD_socket max;
+  time_t start;
+  struct timeval tv;
+  pid_t curl;
+
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  curl = fork_curl ("http://127.0.0.1:1082/");
+  
+  start = time (NULL);
+  while ((time (NULL) - start < 2))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+        {
+          MHD_stop_daemon (d);
+          return 4096;
+        }
+      tv.tv_sec = 0;
+      tv.tv_usec = 1000;
+      select (max + 1, &rs, &ws, &es, &tv);
+      MHD_run (d);
+    }
+  kill_curl (curl);
+  start = time (NULL);
+  while ((time (NULL) - start < 2))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+        {
+          MHD_stop_daemon (d);
+          return 4096;
+        }
+      tv.tv_sec = 0;
+      tv.tv_usec = 1000;
+      select (max + 1, &rs, &ws, &es, &tv);
+      MHD_run (d);
+    }
+  // fprintf (stderr, "Stopping daemon!\n");
+  MHD_stop_daemon (d);
+  if (ok != 0)
+    return 1024;
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  errorCount += testInternalGet ();
+  errorCount += testMultithreadedGet ();
+  errorCount += testMultithreadedPoolGet ();
+  errorCount += testExternalGet ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_get_sendfile.c b/src/testcurl/test_get_sendfile.c
new file mode 100644
index 0000000..f0853b2
--- /dev/null
+++ b/src/testcurl/test_get_sendfile.c
@@ -0,0 +1,500 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007, 2009 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file daemontest_get_sendfile.c
+ * @brief  Testcase for libmicrohttpd response from FD
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include "platform_interface.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#ifndef WINDOWS
+#include <sys/socket.h>
+#include <unistd.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+#define TESTSTR "This is the content of the test file we are sending using sendfile (if available)"
+
+char *sourcefile;
+
+static int oneone;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+
+static int
+ahc_echo (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;
+  const char *me = cls;
+  struct MHD_Response *response;
+  int ret;
+  int fd;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  fd = open (sourcefile, O_RDONLY);
+  if (fd == -1)
+    {
+      fprintf (stderr, "Failed to open `%s': %s\n",
+	       sourcefile,
+	       MHD_strerror_ (errno));
+      exit (1);
+    }
+  response = MHD_create_response_from_fd (strlen (TESTSTR), fd);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+static int
+testInternalGet ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/");
+  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, 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 2;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen (TESTSTR))
+    return 4;
+  if (0 != strncmp (TESTSTR, cbc.buf, strlen (TESTSTR)))
+    return 8;
+  return 0;
+}
+
+static int
+testMultithreadedGet ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  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_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/");
+  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);
+  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, 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 32;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen (TESTSTR))
+    return 64;
+  if (0 != strncmp (TESTSTR, cbc.buf, strlen (TESTSTR)))
+    return 128;
+  return 0;
+}
+
+static int
+testMultithreadedPoolGet ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1081, NULL, NULL, &ahc_echo, "GET",
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/");
+  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);
+  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, 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 32;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen (TESTSTR))
+    return 64;
+  if (0 != strncmp (TESTSTR, cbc.buf, strlen (TESTSTR)))
+    return 128;
+  return 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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  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, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      curl_multi_perform (multi, &running);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      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, &max))
+        {
+          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;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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 (TESTSTR))
+    return 8192;
+  if (0 != strncmp (TESTSTR, cbc.buf, strlen (TESTSTR)))
+    return 16384;
+  return 0;
+}
+
+static int
+testUnknownPortGet ()
+{
+  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,
+                        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, (struct sockaddr *) &addr, &addr_len))
+    return 131072;
+
+  if (addr.sin_family != AF_INET)
+    return 26214;
+
+  snprintf(buf, sizeof(buf), "http://127.0.0.1:%hu/",
+           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, 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 524288;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen (TESTSTR))
+    return 1048576;
+  if (0 != strncmp (TESTSTR, cbc.buf, strlen (TESTSTR)))
+    return 2097152;
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+  const char *tmp;
+  FILE *f;
+
+  if ( (NULL == (tmp = getenv ("TMPDIR"))) &&
+       (NULL == (tmp = getenv ("TMP"))) &&
+       (NULL == (tmp = getenv ("TEMP"))) )
+    tmp = "/tmp";
+  sourcefile = malloc (strlen (tmp) + 32);
+  sprintf (sourcefile,
+	   "%s/%s",
+	   tmp,
+	   "test-mhd-sendfile");
+  f = fopen (sourcefile, "w");
+  if (NULL == f)
+    {
+      fprintf (stderr, "failed to write test file\n");
+      free (sourcefile);
+      return 1;
+    }
+  fwrite (TESTSTR, strlen (TESTSTR), 1, f);
+  fclose (f);
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testInternalGet ();
+  errorCount += testMultithreadedGet ();
+  errorCount += testMultithreadedPoolGet ();
+  errorCount += testExternalGet ();
+  errorCount += testUnknownPortGet ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  unlink (sourcefile);
+  free (sourcefile);
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_iplimit.c b/src/testcurl/test_iplimit.c
new file mode 100644
index 0000000..813fc8b
--- /dev/null
+++ b/src/testcurl/test_iplimit.c
@@ -0,0 +1,313 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_iplimit.c
+ * @brief  Testcase for libmicrohttpd GET operations
+ *         TODO: test parsing of query
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif /* !WIN32_LEAN_AND_MEAN */
+#include <windows.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+static int oneone;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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;
+  const char *me = cls;
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  response = MHD_create_response_from_buffer (strlen (url),
+					      (void *) url,
+					      MHD_RESPMEM_MUST_COPY);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+static int
+testMultithreadedGet ()
+{
+  struct MHD_Daemon *d;
+  char buf[2048];
+  int k;
+  unsigned int success;
+  unsigned int failure;
+
+  /* Test only valid for HTTP/1.1 (uses persistent connections) */
+  if (!oneone)
+    return 0;
+
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1081, NULL, NULL,
+                        &ahc_echo, "GET",
+                        MHD_OPTION_PER_IP_CONNECTION_LIMIT, 2,
+                        MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+
+  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:1081/hello_world");
+          curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+          curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc[i]);
+          curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+          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, 1);
+
+          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;
+      }
+
+      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;
+}
+
+static int
+testMultithreadedPoolGet ()
+{
+  struct MHD_Daemon *d;
+  char buf[2048];
+  int k;
+
+  /* Test only valid for HTTP/1.1 (uses persistent connections) */
+  if (!oneone)
+    return 0;
+
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1081, 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;
+
+  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:1081/hello_world");
+          curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+          curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc[i]);
+          curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+          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, 1);
+
+          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]);
+
+      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)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount |= testMultithreadedGet ();
+  errorCount |= testMultithreadedPoolGet ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_large_put.c b/src/testcurl/test_large_put.c
new file mode 100644
index 0000000..ec0022e
--- /dev/null
+++ b/src/testcurl/test_large_put.c
@@ -0,0 +1,479 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007, 2008 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_large_put.c
+ * @brief  Testcase for libmicrohttpd PUT operations
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+static int oneone;
+
+/**
+ * Do not make this much larger since we will hit the
+ * MHD default buffer limit and the test code is not
+ * written for incremental upload processing...
+ * (larger values will likely cause MHD to generate
+ * an internal server error -- which would be avoided
+ * by writing the putBuffer method in a more general
+ * fashion).
+ */
+#define PUT_SIZE (256 * 1024)
+
+static char *put_buffer;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+putBuffer (void *stream, size_t size, size_t nmemb, void *ptr)
+{
+  unsigned int *pos = ptr;
+  unsigned int wrt;
+
+  wrt = size * nmemb;
+  if (wrt > PUT_SIZE - (*pos))
+    wrt = PUT_SIZE - (*pos);
+  memcpy (stream, &put_buffer[*pos], wrt);
+  (*pos) += wrt;
+  return wrt;
+}
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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)
+{
+  int *done = cls;
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 != strcmp ("PUT", method))
+    return MHD_NO;              /* unexpected method */
+  if ((*done) == 0)
+    {
+      if (*upload_data_size != PUT_SIZE)
+        {
+#if 0
+          fprintf (stderr,
+                   "Waiting for more data (%u/%u)...\n",
+                   *upload_data_size, PUT_SIZE);
+#endif
+          return MHD_YES;       /* not yet ready */
+        }
+      if (0 == memcmp (upload_data, put_buffer, PUT_SIZE))
+        {
+          *upload_data_size = 0;
+        }
+      else
+        {
+          printf ("Invalid upload data!\n");
+          return MHD_NO;
+        }
+      *done = 1;
+      return MHD_YES;
+    }
+  response = MHD_create_response_from_buffer (strlen (url),
+					      (void *) url, 
+					      MHD_RESPMEM_MUST_COPY);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  return ret;
+}
+
+
+static int
+testInternalPut ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  struct CBC cbc;
+  unsigned int pos = 0;
+  int done_flag = 0;
+  CURLcode errornum;
+  char buf[2048];
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1080,
+                        NULL, NULL, &ahc_echo, &done_flag, 
+			MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (1024*1024),
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+  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, (long) PUT_SIZE);
+  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, 150L);
+  // 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 2;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    return 4;
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 8;
+  return 0;
+}
+
+static int
+testMultithreadedPut ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  struct CBC cbc;
+  unsigned int pos = 0;
+  int done_flag = 0;
+  CURLcode errornum;
+  char buf[2048];
+
+  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_echo, &done_flag, 
+			MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (1024*1024),
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  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, (long) PUT_SIZE);
+  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, 150L);
+  // 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 32;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    {
+      fprintf (stderr, "Got invalid response `%.*s'\n", (int)cbc.pos, cbc.buf);
+      return 64;
+    }
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 128;
+  return 0;
+}
+
+static int
+testMultithreadedPoolPut ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  struct CBC cbc;
+  unsigned int pos = 0;
+  int done_flag = 0;
+  CURLcode errornum;
+  char buf[2048];
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1081,
+                        NULL, NULL, &ahc_echo, &done_flag,
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT,
+			MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (1024*1024),
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  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, (long) PUT_SIZE);
+  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, 150L);
+  // 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 32;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    {
+      fprintf (stderr, "Got invalid response `%.*s'\n", (int)cbc.pos, cbc.buf);
+      return 64;
+    }
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 128;
+  return 0;
+}
+
+static int
+testExternalPut ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  struct CBC cbc;
+  CURLM *multi;
+  CURLMcode mret;
+  fd_set rs;
+  fd_set ws;
+  fd_set es;
+  MHD_socket max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+  unsigned int pos = 0;
+  int done_flag = 0;
+  char buf[2048];
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  multi = NULL;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        1082,
+                        NULL, NULL, &ahc_echo, &done_flag,
+                        MHD_OPTION_CONNECTION_MEMORY_LIMIT,
+                        (size_t) (PUT_SIZE * 4), MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+  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, (long) PUT_SIZE);
+  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, 150L);
+  // NOTE: use of CONNECTTIMEOUT without also
+  //   setting NOSIGNAL results in really weird
+  //   crashes on my system!
+  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      curl_multi_perform (multi, &running);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      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, &max))
+        {
+          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;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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"))
+    {
+      fprintf (stderr, "Got invalid response `%.*s'\n", (int)cbc.pos, cbc.buf);
+      return 8192;
+    }
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 16384;
+  return 0;
+}
+
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  put_buffer = malloc (PUT_SIZE);
+  if (NULL == put_buffer) return 1;
+  memset (put_buffer, 1, PUT_SIZE);
+  errorCount += testInternalPut ();
+  errorCount += testMultithreadedPut ();
+  errorCount += testMultithreadedPoolPut ();
+  errorCount += testExternalPut ();
+  free (put_buffer);
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_long_header.c b/src/testcurl/test_long_header.c
new file mode 100644
index 0000000..e1e024b
--- /dev/null
+++ b/src/testcurl/test_long_header.c
@@ -0,0 +1,253 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_long_header.c
+ * @brief  Testcase for libmicrohttpd handling of very long headers
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+/**
+ * We will set the memory available per connection to
+ * half of this value, so the actual value does not have
+ * to be big at all...
+ */
+#define VERY_LONG (1024*10)
+
+static int oneone;
+
+static int
+apc_all (void *cls, const struct sockaddr *addr, socklen_t addrlen)
+{
+  return MHD_YES;
+}
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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)
+{
+  const char *me = cls;
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  response = MHD_create_response_from_buffer (strlen (url),
+					      (void *) url,
+					      MHD_RESPMEM_MUST_COPY);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  return ret;
+}
+
+
+static int
+testLongUrlGet ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  char *url;
+  long code;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */ ,
+                        1080,
+                        &apc_all,
+                        NULL,
+                        &ahc_echo,
+                        "GET",
+                        MHD_OPTION_CONNECTION_MEMORY_LIMIT,
+                        (size_t) (VERY_LONG / 2), MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  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:1080/", strlen ("http://127.0.0.1:1080/"));
+  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, 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 == 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_REQUEST_URI_TOO_LONG)
+    return 8;
+  return 0;
+}
+
+
+static int
+testLongHeaderGet ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  char *url;
+  long code;
+  struct curl_slist *header = NULL;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */ ,
+                        1080,
+                        &apc_all,
+                        NULL,
+                        &ahc_echo,
+                        "GET",
+                        MHD_OPTION_CONNECTION_MEMORY_LIMIT,
+                        (size_t) (VERY_LONG / 2), MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  url = malloc (VERY_LONG);
+  if (url == NULL)
+     {
+	MHD_stop_daemon (d);
+	return 16;
+     }
+  memset (url, 'a', VERY_LONG);
+  url[VERY_LONG - 1] = '\0';
+  url[VERY_LONG / 2] = ':';
+  url[VERY_LONG / 2 + 1] = ' ';
+  header = curl_slist_append (header, url);
+
+  curl_easy_setopt (c, CURLOPT_HTTPHEADER, header);
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+  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, 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 == curl_easy_perform (c))
+    {
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      curl_slist_free_all (header);
+      free (url);
+      return 32;
+    }
+  if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
+    {
+      curl_slist_free_all (header);
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      free (url);
+      return 64;
+    }
+  curl_slist_free_all (header);
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  free (url);
+  if (code != MHD_HTTP_REQUEST_ENTITY_TOO_LARGE)
+    return 128;
+  return 0;
+}
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testLongUrlGet ();
+  errorCount += testLongHeaderGet ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_options.c b/src/testcurl/test_options.c
new file mode 100644
index 0000000..4afe3d4
--- /dev/null
+++ b/src/testcurl/test_options.c
@@ -0,0 +1,124 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007 Christian Grothoff
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING.  If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * @file mhds_get_test.c
+ * @brief  Testcase for libmicrohttpd HTTPS GET operations
+ * @author Sagie Amir
+ */
+
+#include "platform.h"
+#include "microhttpd.h"
+
+#define MHD_E_MEM "Error: memory error\n"
+#define MHD_E_SERVER_INIT "Error: failed to start server\n"
+
+const int DEBUG_GNUTLS_LOG_LEVEL = 0;
+const char *test_file_name = "https_test_file";
+const char test_file_data[] = "Hello World\n";
+
+static int
+ahc_echo (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)
+{
+  return 0;
+}
+
+int
+test_wrap (char *test_name, int (*test) (void))
+{
+  int ret;
+
+  fprintf (stdout, "running test: %s ", test_name);
+  ret = test ();
+  if (ret == 0)
+    {
+      fprintf (stdout, "[pass]\n");
+    }
+  else
+    {
+      fprintf (stdout, "[fail]\n");
+    }
+  return ret;
+}
+
+
+/**
+ * Test daemon initialization with the MHD_OPTION_SOCK_ADDR option
+ */
+static int
+test_ip_addr_option ()
+{
+  struct MHD_Daemon *d;
+  struct sockaddr_in daemon_ip_addr;
+#if HAVE_INET6
+  struct sockaddr_in6 daemon_ip_addr6;
+#endif
+
+  memset (&daemon_ip_addr, 0, sizeof (struct sockaddr_in));
+  daemon_ip_addr.sin_family = AF_INET;
+  daemon_ip_addr.sin_port = htons (4233);
+  daemon_ip_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+
+#if HAVE_INET6
+  memset (&daemon_ip_addr6, 0, sizeof (struct sockaddr_in6));
+  daemon_ip_addr6.sin6_family = AF_INET6;
+  daemon_ip_addr6.sin6_port = htons (4233);
+  daemon_ip_addr6.sin6_addr = in6addr_loopback;
+#endif
+
+  d = MHD_start_daemon (MHD_USE_DEBUG, 4233,
+                        NULL, NULL, &ahc_echo, NULL, MHD_OPTION_SOCK_ADDR,
+                        &daemon_ip_addr, MHD_OPTION_END);
+
+  if (d == 0)
+    return -1;
+
+  MHD_stop_daemon (d);
+
+#if HAVE_INET6
+  d = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_IPv6, 4233,
+                        NULL, NULL, &ahc_echo, NULL, MHD_OPTION_SOCK_ADDR,
+                        &daemon_ip_addr6, MHD_OPTION_END);
+
+  if (d == 0)
+    return -1;
+
+  MHD_stop_daemon (d);
+#endif
+
+  return 0;
+}
+
+/* setup a temporary transfer test file */
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  errorCount += test_wrap ("ip addr option", &test_ip_addr_option);
+
+  return errorCount != 0;
+}
diff --git a/src/testcurl/test_parse_cookies.c b/src/testcurl/test_parse_cookies.c
new file mode 100644
index 0000000..7d70867
--- /dev/null
+++ b/src/testcurl/test_parse_cookies.c
@@ -0,0 +1,250 @@
+
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_parse_cookies.c
+ * @brief  Testcase for HTTP cookie parsing
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+static int oneone;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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;
+  const char *me = cls;
+  struct MHD_Response *response;
+  int ret;
+  const char *hdr;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  ret = 0;
+
+  hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name1");
+  if ((hdr == NULL) || (0 != strcmp (hdr, "var1")))
+    abort ();
+  hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name2");
+  if ((hdr == NULL) || (0 != strcmp (hdr, "var2")))
+    abort ();
+  hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name3");
+  if ((hdr == NULL) || (0 != strcmp (hdr, "")))
+    abort ();
+  hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name4");
+  if ((hdr == NULL) || (0 != strcmp (hdr, "var4 with spaces")))
+    abort ();
+  response = MHD_create_response_from_buffer (strlen (url),
+					      (void *) url,
+					      MHD_RESPMEM_PERSISTENT);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        21080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:21080/hello_world");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  /* note that the string below intentionally uses the
+     various ways cookies can be specified to exercise the
+     parser! Do not change! */
+  curl_easy_setopt (c, CURLOPT_COOKIE,
+                    "name1=var1; name2=var2,name3 ;name4=\"var4 with spaces\";");
+  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, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      curl_multi_perform (multi, &running);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      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, &max))
+        {
+          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;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testExternalGet ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_post.c b/src/testcurl/test_post.c
new file mode 100644
index 0000000..49bf30a
--- /dev/null
+++ b/src/testcurl/test_post.c
@@ -0,0 +1,654 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_post.c
+ * @brief  Testcase for libmicrohttpd POST operations using URL-encoding
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif /* !WIN32_LEAN_AND_MEAN */
+#include <windows.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+#define POST_DATA "name=daniel&project=curl"
+
+static int oneone;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+
+static void
+completed_cb (void *cls,
+	      struct MHD_Connection *connection,
+	      void **con_cls,
+	      enum MHD_RequestTerminationCode toe)
+{
+  struct MHD_PostProcessor *pp = *con_cls;
+
+  if (NULL != pp)
+    MHD_destroy_post_processor (pp);   
+  *con_cls = NULL;
+}
+
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  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 *filename,
+               const char *content_type,
+               const char *transfer_encoding,
+               const char *value, uint64_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, size_t *upload_data_size,
+          void **unused)
+{
+  static int eok;
+  struct MHD_Response *response;
+  struct MHD_PostProcessor *pp;
+  int ret;
+
+  if (0 != strcmp ("POST", method))
+    {
+      printf ("METHOD: %s\n", method);
+      return MHD_NO;            /* unexpected method */
+    }
+  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_buffer (strlen (url),
+						  (void *) url,
+						  MHD_RESPMEM_MUST_COPY);
+      ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+      MHD_destroy_response (response);
+      MHD_destroy_post_processor (pp);
+      *unused = NULL;
+      return ret;
+    }
+  *upload_data_size = 0;
+  return MHD_YES;
+}
+
+
+static int
+testInternalPost ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1080, NULL, NULL, &ahc_echo, NULL, 
+			MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,			
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+  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, 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, 150L);
+  // 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 2;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    return 4;
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 8;
+  return 0;
+}
+
+static int
+testMultithreadedPost ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  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_echo, NULL, 
+			MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,			
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  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, 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, 150L);
+  // 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 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;
+}
+
+static int
+testMultithreadedPoolPost ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1081, NULL, NULL, &ahc_echo, NULL,
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT,
+			MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,			
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  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, 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, 150L);
+  // 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 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;
+}
+
+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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        1082, NULL, NULL, &ahc_echo, NULL, 
+			MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,			
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+  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, 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, 150L);
+  // NOTE: use of CONNECTTIMEOUT without also
+  //   setting NOSIGNAL results in really weird
+  //   crashes on my system!
+  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      curl_multi_perform (multi, &running);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      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, &max))
+        {
+          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;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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;
+}
+
+
+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_buffer (0, NULL, 
+						  MHD_RESPMEM_PERSISTENT);
+      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://127.0.0.1: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, 150L);
+  // 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)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testMultithreadedPostCancel ();
+  errorCount += testInternalPost ();
+  errorCount += testMultithreadedPost ();
+  errorCount += testMultithreadedPoolPost ();
+  errorCount += testExternalPost ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_post_loop.c b/src/testcurl/test_post_loop.c
new file mode 100644
index 0000000..fe8d25c
--- /dev/null
+++ b/src/testcurl/test_post_loop.c
@@ -0,0 +1,531 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file daemontest_post_loop.c
+ * @brief  Testcase for libmicrohttpd POST operations using URL-encoding
+ * @author Christian Grothoff (inspired by bug report #1296)
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <gauger.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+#define POST_DATA "<?xml version='1.0' ?>\n<xml>\n<data-id>1</data-id>\n</xml>\n"
+
+#define LOOPCOUNT 1000
+
+static int oneone;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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 **mptr)
+{
+  static int marker;
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 != strcmp ("POST", method))
+    {
+      printf ("METHOD: %s\n", method);
+      return MHD_NO;            /* unexpected method */
+    }
+  if ((*mptr != NULL) && (0 == *upload_data_size))
+    {
+      if (*mptr != &marker)
+        abort ();
+      response = MHD_create_response_from_buffer (2, "OK", 
+						  MHD_RESPMEM_PERSISTENT);
+      ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+      MHD_destroy_response (response);
+      *mptr = NULL;
+      return ret;
+    }
+  if (strlen (POST_DATA) != *upload_data_size)
+    return MHD_YES;
+  *upload_data_size = 0;
+  *mptr = &marker;
+  return MHD_YES;
+}
+
+
+static int
+testInternalPost ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+  int i;
+  char url[1024];
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1080, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  for (i = 0; i < LOOPCOUNT; i++)
+    {
+      if (99 == i % 100)
+        fprintf (stderr, ".");
+      c = curl_easy_init ();
+      cbc.pos = 0;
+      buf[0] = '\0';
+      sprintf (url, "http://127.0.0.1:1080/hw%d", 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, 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, 150L);
+      // 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 2;
+        }
+      curl_easy_cleanup (c);
+      if ((buf[0] != 'O') || (buf[1] != 'K'))
+        {
+          MHD_stop_daemon (d);
+          return 4;
+        }
+    }
+  MHD_stop_daemon (d);
+  if (LOOPCOUNT >= 99)
+    fprintf (stderr, "\n");
+  return 0;
+}
+
+static int
+testMultithreadedPost ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+  int i;
+  char url[1024];
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
+                        1081, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  for (i = 0; i < LOOPCOUNT; i++)
+    {
+      if (99 == i % 100)
+        fprintf (stderr, ".");
+      c = curl_easy_init ();
+      cbc.pos = 0;
+      buf[0] = '\0';
+      sprintf (url, "http://127.0.0.1:1081/hw%d", 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, 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, 150L);
+      // 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 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
+testMultithreadedPoolPost ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+  int i;
+  char url[1024];
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1081, NULL, NULL, &ahc_echo, NULL,
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  for (i = 0; i < LOOPCOUNT; i++)
+    {
+      if (99 == i % 100)
+        fprintf (stderr, ".");
+      c = curl_easy_init ();
+      cbc.pos = 0;
+      buf[0] = '\0';
+      sprintf (url, "http://127.0.0.1:1081/hw%d", 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, 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, 150L);
+      // 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 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
+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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+  int i;
+  unsigned long long timeout;
+  long ctimeout;
+  char url[1024];
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        1082, NULL, NULL, &ahc_echo, NULL, MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  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';
+      sprintf (url, "http://127.0.0.1:1082/hw%d", 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, 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, 150L);
+      // NOTE: use of CONNECTTIMEOUT without also
+      //   setting NOSIGNAL results in really weird
+      //   crashes on my system!
+      curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+      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))
+        {
+          max = 0;
+          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, &max);
+          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, &max))
+            {
+              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 < 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 (max + 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;
+}
+
+
+/**
+ * Time this round was started.
+ */
+static unsigned long long start_time;
+
+
+/**
+ * Get the current timestamp 
+ *
+ * @return current time in ms
+ */
+static unsigned long long 
+now ()
+{
+  struct timeval tv;
+
+  gettimeofday (&tv, NULL);
+  return (((unsigned long long) tv.tv_sec * 1000LL) +
+	  ((unsigned long long) tv.tv_usec / 1000LL));
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  start_time = now();
+  errorCount += testInternalPost ();
+  fprintf (stderr,
+	   oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
+	   "internal select",
+	   (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
+  GAUGER ("internal select",
+	  oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)",
+	  (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0),
+	  "requests/s");
+  start_time = now();
+  errorCount += testMultithreadedPost ();
+  fprintf (stderr,
+	   oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
+	   "multithreaded post",
+	   (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
+  GAUGER ("Multithreaded select",
+	  oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)",
+	  (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0),
+	  "requests/s");
+  start_time = now();
+  errorCount += testMultithreadedPoolPost ();
+  fprintf (stderr,
+	   oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
+	   "thread with pool",
+	   (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
+  GAUGER ("thread with pool",
+	  oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)",
+	  (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0),
+	  "requests/s");
+  start_time = now();
+  errorCount += testExternalPost ();
+  fprintf (stderr,
+	   oneone ? "%s: Sequential POSTs (http/1.1) %f/s\n" : "%s: Sequential POSTs (http/1.0) %f/s\n",
+	   "external select",
+	   (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0));
+  GAUGER ("external select",
+	  oneone ? "Sequential POSTs (http/1.1)" : "Sequential POSTs (http/1.0)",
+	  (double) 1000 * LOOPCOUNT / (now() - start_time + 1.0),
+	  "requests/s");
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_postform.c b/src/testcurl/test_postform.c
new file mode 100644
index 0000000..450eb6f
--- /dev/null
+++ b/src/testcurl/test_postform.c
@@ -0,0 +1,498 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_postform.c
+ * @brief  Testcase for libmicrohttpd POST operations using multipart/postform data
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_GCRYPT_H
+#include <gcrypt.h>
+#endif
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+static int oneone;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+
+static void
+completed_cb (void *cls,
+	      struct MHD_Connection *connection,
+	      void **con_cls,
+	      enum MHD_RequestTerminationCode toe)
+{
+  struct MHD_PostProcessor *pp = *con_cls;
+
+  if (NULL != pp)
+    MHD_destroy_post_processor (pp);
+  *con_cls = NULL;
+}
+
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  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 *filename,
+               const char *content_type,
+               const char *transfer_encoding,
+               const char *value, uint64_t off, size_t size)
+{
+  int *eok = cls;
+
+#if 0
+  fprintf (stderr, "PI sees %s-%.*s\n", key, size, value);
+#endif
+  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, size_t *upload_data_size,
+          void **unused)
+{
+  static int eok;
+  struct MHD_Response *response;
+  struct MHD_PostProcessor *pp;
+  int ret;
+
+  if (0 != strcmp ("POST", method))
+    {
+      printf ("METHOD: %s\n", method);
+      return MHD_NO;            /* unexpected method */
+    }
+  pp = *unused;
+  if (pp == NULL)
+    {
+      eok = 0;
+      pp = MHD_create_post_processor (connection, 1024, &post_iterator, &eok);
+      if (pp == NULL)
+        abort ();
+      *unused = pp;
+    }
+  MHD_post_process (pp, upload_data, *upload_data_size);
+  if ((eok == 3) && (0 == *upload_data_size))
+    {
+      response = MHD_create_response_from_buffer (strlen (url),
+						  (void *) url,
+						  MHD_RESPMEM_MUST_COPY);
+      ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+      MHD_destroy_response (response);
+      MHD_destroy_post_processor (pp);
+      *unused = NULL;
+      return ret;
+    }
+  *upload_data_size = 0;
+  return MHD_YES;
+}
+
+static struct curl_httppost *
+make_form ()
+{
+  struct curl_httppost *post = NULL;
+  struct curl_httppost *last = NULL;
+
+  curl_formadd (&post, &last, CURLFORM_COPYNAME, "name",
+                CURLFORM_COPYCONTENTS, "daniel", CURLFORM_END);
+  curl_formadd (&post, &last, CURLFORM_COPYNAME, "project",
+                CURLFORM_COPYCONTENTS, "curl", CURLFORM_END);
+  return post;
+}
+
+
+static int
+testInternalPost ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+  struct curl_httppost *pd;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1080, NULL, NULL, &ahc_echo, NULL, 
+			MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,			
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  pd = make_form ();
+  curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
+  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, 150L);
+  // 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);
+      curl_formfree (pd);
+      MHD_stop_daemon (d);
+      return 2;
+    }
+  curl_easy_cleanup (c);
+  curl_formfree (pd);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    return 4;
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 8;
+  return 0;
+}
+
+static int
+testMultithreadedPost ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+  struct curl_httppost *pd;
+
+  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_echo, NULL, 
+			MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,			
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  pd = make_form ();
+  curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
+  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, 5L);
+  // 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);
+      curl_formfree (pd);
+      MHD_stop_daemon (d);
+      return 32;
+    }
+  curl_easy_cleanup (c);
+  curl_formfree (pd);
+  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
+testMultithreadedPoolPost ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+  struct curl_httppost *pd;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1081, NULL, NULL, &ahc_echo, NULL,
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT,
+			MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,			
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  pd = make_form ();
+  curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
+  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, 5L);
+  // 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);
+      curl_formfree (pd);
+      MHD_stop_daemon (d);
+      return 32;
+    }
+  curl_easy_cleanup (c);
+  curl_formfree (pd);
+  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
+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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+  struct curl_httppost *pd;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        1082, NULL, NULL, &ahc_echo, NULL, 
+			MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,			
+			MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  pd = make_form ();
+  curl_easy_setopt (c, CURLOPT_HTTPPOST, pd);
+  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, 150L);
+  // NOTE: use of CONNECTTIMEOUT without also
+  //   setting NOSIGNAL results in really weird
+  //   crashes on my system!
+  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+
+
+  multi = curl_multi_init ();
+  if (multi == NULL)
+    {
+      curl_easy_cleanup (c);
+      curl_formfree (pd);
+      MHD_stop_daemon (d);
+      return 512;
+    }
+  mret = curl_multi_add_handle (multi, c);
+  if (mret != CURLM_OK)
+    {
+      curl_multi_cleanup (multi);
+      curl_formfree (pd);
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      return 1024;
+    }
+  start = time (NULL);
+  while ((time (NULL) - start < 5) && (multi != NULL))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      curl_multi_perform (multi, &running);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      if (mret != CURLM_OK)
+        {
+          curl_multi_remove_handle (multi, c);
+          curl_multi_cleanup (multi);
+          curl_easy_cleanup (c);
+          MHD_stop_daemon (d);
+          curl_formfree (pd);
+          return 2048;
+        }
+      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+        {
+          curl_multi_remove_handle (multi, c);
+          curl_multi_cleanup (multi);
+          curl_easy_cleanup (c);
+          curl_formfree (pd);
+          MHD_stop_daemon (d);
+          return 4096;
+        }
+      tv.tv_sec = 0;
+      tv.tv_usec = 1000;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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);
+    }
+  curl_formfree (pd);
+  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;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+#ifdef HAVE_GCRYPT_H
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+#ifdef GCRYCTL_INITIALIZATION_FINISHED
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+#endif
+#endif
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testInternalPost ();
+  errorCount += testMultithreadedPost ();
+  errorCount += testMultithreadedPoolPost ();
+  errorCount += testExternalPost ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_process_arguments.c b/src/testcurl/test_process_arguments.c
new file mode 100644
index 0000000..a3e5841
--- /dev/null
+++ b/src/testcurl/test_process_arguments.c
@@ -0,0 +1,249 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007, 2013 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_process_arguments.c
+ * @brief  Testcase for HTTP URI arguments
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+static int oneone;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+
+static int
+ahc_echo (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;
+  const char *me = cls;
+  struct MHD_Response *response;
+  int ret;
+  const char *hdr;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  hdr = MHD_lookup_connection_value (connection, MHD_GET_ARGUMENT_KIND, "k");
+  if ((hdr == NULL) || (0 != strcmp (hdr, "v x")))
+    abort ();
+  hdr = MHD_lookup_connection_value (connection,
+                                     MHD_GET_ARGUMENT_KIND, "hash");
+  if ((hdr == NULL) || (0 != strcmp (hdr, "#foo")))
+    abort ();
+  hdr = MHD_lookup_connection_value (connection,
+                                     MHD_GET_ARGUMENT_KIND, "space");
+  if ((hdr == NULL) || (0 != strcmp (hdr, "\240bar")))
+    abort ();
+  if (3 != MHD_get_connection_values (connection,
+				      MHD_GET_ARGUMENT_KIND,
+				      NULL, NULL))
+    abort ();
+  response = MHD_create_response_from_buffer (strlen (url),
+					      (void *) url,
+					      MHD_RESPMEM_MUST_COPY);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        21080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL,
+                    "http://127.0.0.1:21080/hello+world?k=v+x&hash=%23foo&space=%A0bar");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  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, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      curl_multi_perform (multi, &running);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      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, &max))
+        {
+          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;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testExternalGet ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_process_headers.c b/src/testcurl/test_process_headers.c
new file mode 100644
index 0000000..4a219fb
--- /dev/null
+++ b/src/testcurl/test_process_headers.c
@@ -0,0 +1,434 @@
+
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_process_headers.c
+ * @brief  Testcase for HTTP header access
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+static int oneone;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int
+kv_cb (void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
+{
+  if ((0 == strcmp (key, MHD_HTTP_HEADER_HOST)) &&
+      (0 == strcmp (value, "127.0.0.1:21080")) && (kind == MHD_HEADER_KIND))
+    {
+      *((int *) cls) = 1;
+      return MHD_NO;
+    }
+  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, size_t *upload_data_size,
+          void **unused)
+{
+  static int ptr;
+  const char *me = cls;
+  struct MHD_Response *response;
+  int ret;
+  const char *hdr;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  ret = 0;
+  MHD_get_connection_values (connection, MHD_HEADER_KIND, &kv_cb, &ret);
+  if (ret != 1)
+    abort ();
+  hdr = MHD_lookup_connection_value (connection, MHD_HEADER_KIND, "NotFound");
+  if (hdr != NULL)
+    abort ();
+  hdr = MHD_lookup_connection_value (connection,
+                                     MHD_HEADER_KIND, MHD_HTTP_HEADER_ACCEPT);
+  if ((hdr == NULL) || (0 != strcmp (hdr, "*/*")))
+    abort ();
+  hdr = MHD_lookup_connection_value (connection,
+                                     MHD_HEADER_KIND, MHD_HTTP_HEADER_HOST);
+  if ((hdr == NULL) || (0 != strcmp (hdr, "127.0.0.1:21080")))
+    abort ();
+  MHD_set_connection_value (connection,
+                            MHD_HEADER_KIND, "FakeHeader", "NowPresent");
+  hdr = MHD_lookup_connection_value (connection,
+                                     MHD_HEADER_KIND, "FakeHeader");
+  if ((hdr == NULL) || (0 != strcmp (hdr, "NowPresent")))
+    abort ();
+
+  response = MHD_create_response_from_buffer (strlen (url),
+					      (void *) url,
+					      MHD_RESPMEM_MUST_COPY);
+  MHD_add_response_header (response, "MyHeader", "MyValue");
+  hdr = MHD_get_response_header (response, "MyHeader");
+  if (0 != strcmp ("MyValue", hdr))
+    abort ();
+  MHD_add_response_header (response, "MyHeader", "MyValueToo");
+  if (MHD_YES != MHD_del_response_header (response, "MyHeader", "MyValue"))
+    abort ();
+  hdr = MHD_get_response_header (response, "MyHeader");
+  if (0 != strcmp ("MyValueToo", hdr))
+    abort ();
+  if (1 != MHD_get_response_headers (response, NULL, NULL))
+    abort ();
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+static int
+testInternalGet ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        21080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:21080/hello_world");
+  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, 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 2;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    return 4;
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 8;
+  return 0;
+}
+
+static int
+testMultithreadedGet ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
+                        21080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:21080/hello_world");
+  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);
+  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, 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 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;
+}
+
+static int
+testMultithreadedPoolGet ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        21080, NULL, NULL, &ahc_echo, "GET",
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:21080/hello_world");
+  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);
+  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, 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 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;
+}
+
+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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        21080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:21080/hello_world");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  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, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      curl_multi_perform (multi, &running);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      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, &max))
+        {
+          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;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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;
+}
+
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  errorCount += testMultithreadedGet ();
+  errorCount += testMultithreadedPoolGet ();
+  errorCount += testExternalGet ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_put.c b/src/testcurl/test_put.c
new file mode 100644
index 0000000..fe1d8db
--- /dev/null
+++ b/src/testcurl/test_put.c
@@ -0,0 +1,440 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file daemontest_put.c
+ * @brief  Testcase for libmicrohttpd PUT operations
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+static int oneone;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+putBuffer (void *stream, size_t size, size_t nmemb, void *ptr)
+{
+  unsigned int *pos = ptr;
+  unsigned int wrt;
+
+  wrt = size * nmemb;
+  if (wrt > 8 - (*pos))
+    wrt = 8 - (*pos);
+  memcpy (stream, &("Hello123"[*pos]), wrt);
+  (*pos) += wrt;
+  return wrt;
+}
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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)
+{
+  int *done = cls;
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 != strcmp ("PUT", method))
+    return MHD_NO;              /* unexpected method */
+  if ((*done) == 0)
+    {
+      if (*upload_data_size != 8)
+        return MHD_YES;         /* not yet ready */
+      if (0 == memcmp (upload_data, "Hello123", 8))
+        {
+          *upload_data_size = 0;
+        }
+      else
+        {
+          printf ("Invalid upload data `%8s'!\n", upload_data);
+          return MHD_NO;
+        }
+      *done = 1;
+      return MHD_YES;
+    }
+  response = MHD_create_response_from_buffer (strlen (url), (void*) url,
+					      MHD_RESPMEM_MUST_COPY);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  return ret;
+}
+
+
+static int
+testInternalPut ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  unsigned int pos = 0;
+  int done_flag = 0;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1080,
+                        NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+  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, 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, 150L);
+  // 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 2;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    return 4;
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 8;
+  return 0;
+}
+
+static int
+testMultithreadedPut ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  unsigned int pos = 0;
+  int done_flag = 0;
+  CURLcode errornum;
+
+  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_echo, &done_flag, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  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, 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, 150L);
+  // 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 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;
+}
+
+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;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1081,
+                        NULL, NULL, &ahc_echo, &done_flag,
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1081/hello_world");
+  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, 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, 150L);
+  // 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 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;
+}
+
+
+static int
+testExternalPut ()
+{
+  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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+  unsigned int pos = 0;
+  int done_flag = 0;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        1082,
+                        NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1082/hello_world");
+  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, 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, 150L);
+  // NOTE: use of CONNECTTIMEOUT without also
+  //   setting NOSIGNAL results in really weird
+  //   crashes on my system!
+  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      curl_multi_perform (multi, &running);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      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, &max))
+        {
+          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;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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;
+}
+
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testInternalPut ();
+  errorCount += testMultithreadedPut ();
+  errorCount += testMultithreadedPoolPut ();
+  errorCount += testExternalPut ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_put_chunked.c b/src/testcurl/test_put_chunked.c
new file mode 100644
index 0000000..b2fa322
--- /dev/null
+++ b/src/testcurl/test_put_chunked.c
@@ -0,0 +1,448 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file daemontest_put_chunked.c
+ * @brief Testcase for libmicrohttpd PUT operations with chunked encoding
+ *        for the upload data
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+putBuffer (void *stream, size_t size, size_t nmemb, void *ptr)
+{
+  unsigned int *pos = ptr;
+  unsigned int wrt;
+
+  wrt = size * nmemb;
+  if (wrt > 8 - (*pos))
+    wrt = 8 - (*pos);
+  if (wrt > 4)
+    wrt = 4;                    /* only send half at first => force multiple chunks! */
+  memcpy (stream, &("Hello123"[*pos]), wrt);
+  (*pos) += wrt;
+  return wrt;
+}
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int
+ahc_echo (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)
+{
+  int *done = cls;
+  struct MHD_Response *response;
+  int ret;
+  int have;
+
+  if (0 != strcmp ("PUT", method))
+    return MHD_NO;              /* unexpected method */
+  if ((*done) < 8)
+    {
+      have = *upload_data_size;
+      if (have + *done > 8)
+        {
+          printf ("Invalid upload data `%8s'!\n", upload_data);
+          return MHD_NO;
+        }
+      if (0 == memcmp (upload_data, &"Hello123"[*done], have))
+        {
+          *done += have;
+          *upload_data_size = 0;
+        }
+      else
+        {
+          printf ("Invalid upload data `%8s'!\n", upload_data);
+          return MHD_NO;
+        }
+#if 0
+      fprintf (stderr, "Not ready for response: %u/%u\n", *done, 8);
+#endif
+      return MHD_YES;
+    }
+  response = MHD_create_response_from_buffer (strlen (url),
+					      (void *) url,
+					      MHD_RESPMEM_MUST_COPY);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  return ret;
+}
+
+
+static int
+testInternalPut ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  unsigned int pos = 0;
+  int done_flag = 0;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        11080,
+                        NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world");
+  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);
+  /*
+     // by not giving the file size, we force chunking!
+     curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+   */
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+  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, 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 2;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    return 4;
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 8;
+  return 0;
+}
+
+static int
+testMultithreadedPut ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  unsigned int pos = 0;
+  int done_flag = 0;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
+                        11081,
+                        NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+  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);
+  /*
+     // by not giving the file size, we force chunking!
+     curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+   */
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+  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, 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 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;
+}
+
+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;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        11081,
+                        NULL, NULL, &ahc_echo, &done_flag,
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11081/hello_world");
+  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);
+  /*
+     // by not giving the file size, we force chunking!
+     curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+   */
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+  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, 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 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;
+}
+
+
+static int
+testExternalPut ()
+{
+  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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+  unsigned int pos = 0;
+  int done_flag = 0;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        11082,
+                        NULL, NULL, &ahc_echo, &done_flag, MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11082/hello_world");
+  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);
+  /*
+     // by not giving the file size, we force chunking!
+     curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+   */
+  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
+  curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
+  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, 1);
+
+
+  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))
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      curl_multi_perform (multi, &running);
+      mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+      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, &max))
+        {
+          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;
+      select (max + 1, &rs, &ws, &es, &tv);
+      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;
+}
+
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testInternalPut ();
+  errorCount += testMultithreadedPut ();
+  errorCount += testMultithreadedPoolPut ();
+  errorCount += testExternalPut ();
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_quiesce.c b/src/testcurl/test_quiesce.c
new file mode 100644
index 0000000..17adcb2
--- /dev/null
+++ b/src/testcurl/test_quiesce.c
@@ -0,0 +1,457 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2013, 2015 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file test_quiesce.c
+ * @brief  Testcase for libmicrohttpd quiescing
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include "platform_interface.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <pthread.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#include <sys/socket.h>
+#endif
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+
+static int
+ahc_echo (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;
+  const char *me = cls;
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  *unused = NULL;
+  response = MHD_create_response_from_buffer (strlen (url),
+  				      (void *) url,
+					      MHD_RESPMEM_MUST_COPY);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+static void
+request_completed (void *cls, struct MHD_Connection *connection,
+		   void **con_cls, enum MHD_RequestTerminationCode code)
+{
+  int *done = (int *)cls;
+  *done = 1;
+}
+
+
+static void *
+ServeOneRequest(void *param)
+{
+  struct MHD_Daemon *d;
+  fd_set rs;
+  fd_set ws;
+  fd_set es;
+  MHD_socket fd, max;
+  time_t start;
+  struct timeval tv;
+  int done = 0;
+
+  fd = (MHD_socket) (intptr_t) param;
+
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        1082, NULL, NULL, &ahc_echo, "GET",
+                        MHD_OPTION_LISTEN_SOCKET, fd,
+                        MHD_OPTION_NOTIFY_COMPLETED, &request_completed, &done,
+                        MHD_OPTION_END);
+  if (d == NULL)
+    return "MHD_start_daemon() failed";
+
+  start = time (NULL);
+  while ((time (NULL) - start < 5) && done == 0)
+    {
+      max = 0;
+      FD_ZERO (&rs);
+      FD_ZERO (&ws);
+      FD_ZERO (&es);
+      if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
+        {
+          MHD_stop_daemon (d);
+          MHD_socket_close_(fd);
+          return "MHD_get_fdset() failed";
+        }
+      tv.tv_sec = 0;
+      tv.tv_usec = 1000;
+      MHD_SYS_select_ (max + 1, &rs, &ws, &es, &tv);
+      MHD_run (d);
+    }
+  MHD_stop_daemon (d);
+  MHD_socket_close_(fd);
+  return NULL;
+}
+
+
+static CURL *
+setupCURL (void *cbc)
+{
+  CURL *c;
+
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world");
+  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_MS, 150L);
+  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT_MS, 150L);
+  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);
+
+  return c;
+}
+
+
+static int
+testGet (int type, int pool_count, int poll_flag)
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+  MHD_socket fd;
+  pthread_t thrd;
+  const char *thrdRet;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  if (pool_count > 0) {
+    d = MHD_start_daemon (type | MHD_USE_DEBUG | MHD_USE_PIPE_FOR_SHUTDOWN | poll_flag,
+                          11080, NULL, NULL, &ahc_echo, "GET",
+                          MHD_OPTION_THREAD_POOL_SIZE, pool_count, MHD_OPTION_END);
+
+  } else {
+    d = MHD_start_daemon (type | MHD_USE_DEBUG | MHD_USE_PIPE_FOR_SHUTDOWN | poll_flag,
+                          11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  }
+  if (d == NULL)
+    return 1;
+
+  c = setupCURL(&cbc);
+
+  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;
+    }
+
+  if (cbc.pos != strlen ("/hello_world")) {
+    curl_easy_cleanup (c);
+    MHD_stop_daemon (d);
+    return 4;
+  }
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) {
+    curl_easy_cleanup (c);
+    MHD_stop_daemon (d);
+    return 8;
+  }
+
+  fd = MHD_quiesce_daemon (d);
+  if (0 != pthread_create(&thrd, NULL, &ServeOneRequest, (void*)(intptr_t) fd))
+    {
+      fprintf (stderr, "pthread_create failed\n");
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      return 16;
+    }
+
+  cbc.pos = 0;
+  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;
+    }
+
+  if (0 != pthread_join(thrd, (void**)&thrdRet))
+    {
+      fprintf (stderr, "pthread_join failed\n");
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      return 16;
+    }
+  if (NULL != thrdRet)
+    {
+      fprintf (stderr, "ServeOneRequest() error: %s\n", thrdRet);
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      return 16;
+    }
+
+  if (cbc.pos != strlen ("/hello_world"))
+    {
+      fprintf(stderr, "%s\n", cbc.buf);
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      MHD_socket_close_(fd);
+      return 4;
+    }
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    {
+      fprintf(stderr, "%s\n", cbc.buf);
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      MHD_socket_close_(fd);
+      return 8;
+    }
+
+  /* at this point, the forked server quit, and the new
+   * server has quiesced, so new requests should fail
+   */
+  if (CURLE_OK == (errornum = curl_easy_perform (c)))
+    {
+      fprintf (stderr, "curl_easy_perform should fail\n");
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      MHD_socket_close_(fd);
+      return 2;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  MHD_socket_close_(fd);
+
+  return 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 max;
+  int running;
+  struct CURLMsg *msg;
+  time_t start;
+  struct timeval tv;
+  int i;
+  MHD_socket fd;
+
+  multi = NULL;
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 256;
+  c = setupCURL(&cbc);
+
+  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;
+    }
+
+  for (i = 0; i < 2; i++) {
+    start = time (NULL);
+    while ((time (NULL) - start < 5) && (multi != NULL))
+      {
+        max = 0;
+        FD_ZERO (&rs);
+        FD_ZERO (&ws);
+        FD_ZERO (&es);
+        curl_multi_perform (multi, &running);
+        mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
+        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, &max))
+          {
+            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;
+        select (max + 1, &rs, &ws, &es, &tv);
+        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 (i == 0 && msg->data.result != CURLE_OK)
+                  printf ("%s failed at %s:%d: `%s'\n",
+                          "curl_multi_perform",
+                          __FILE__,
+                          __LINE__, curl_easy_strerror (msg->data.result));
+                else if (i == 1 && msg->data.result == CURLE_OK)
+                  printf ("%s should have failed at %s:%d\n",
+                          "curl_multi_perform",
+                          __FILE__,
+                          __LINE__);
+                curl_multi_remove_handle (multi, c);
+                curl_multi_cleanup (multi);
+                curl_easy_cleanup (c);
+                c = NULL;
+                multi = NULL;
+              }
+          }
+        MHD_run (d);
+      }
+
+      if (i == 0) {
+        /* quiesce the daemon on the 1st iteration, so the 2nd should fail */
+        fd = MHD_quiesce_daemon(d);
+	if (MHD_INVALID_SOCKET == fd)
+	  abort ();
+	MHD_socket_close_ (fd);
+        c = setupCURL (&cbc);
+        multi = curl_multi_init ();
+        mret = curl_multi_add_handle (multi, c);
+      }
+    }
+  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;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testGet (MHD_USE_SELECT_INTERNALLY, 0, 0);
+  errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION, 0, 0);
+  errorCount += testGet (MHD_USE_SELECT_INTERNALLY, CPU_COUNT, 0);
+  errorCount += testExternalGet ();
+  if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
+    {
+      errorCount += testGet(MHD_USE_SELECT_INTERNALLY, 0, MHD_USE_POLL);
+      errorCount += testGet (MHD_USE_THREAD_PER_CONNECTION, 0, MHD_USE_POLL);
+      errorCount += testGet (MHD_USE_SELECT_INTERNALLY, CPU_COUNT, MHD_USE_POLL);
+    }
+  if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
+    {
+      errorCount += testGet (MHD_USE_SELECT_INTERNALLY, 0, MHD_USE_EPOLL_LINUX_ONLY);
+      errorCount += testGet (MHD_USE_SELECT_INTERNALLY, CPU_COUNT, MHD_USE_EPOLL_LINUX_ONLY);
+    }
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_start_stop.c b/src/testcurl/test_start_stop.c
new file mode 100644
index 0000000..a708341
--- /dev/null
+++ b/src/testcurl/test_start_stop.c
@@ -0,0 +1,129 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2011 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_start_stop.c
+ * @brief  test for #1901 (start+stop)
+ * @author Christian Grothoff
+ */
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+
+#if defined(CPU_COUNT) && (CPU_COUNT+0) < 2
+#undef CPU_COUNT
+#endif
+#if !defined(CPU_COUNT)
+#define CPU_COUNT 2
+#endif
+
+
+static int
+ahc_echo (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)
+{
+  return MHD_NO;
+}
+
+
+static int
+testInternalGet (int poll_flag)
+{
+  struct MHD_Daemon *d;
+
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag,
+                        11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  MHD_stop_daemon (d);
+  return 0;
+}
+
+static int
+testMultithreadedGet (int poll_flag)
+{
+  struct MHD_Daemon *d;
+
+  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG  | poll_flag,
+                        1081, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 2;
+  MHD_stop_daemon (d);
+  return 0;
+}
+
+static int
+testMultithreadedPoolGet (int poll_flag)
+{
+  struct MHD_Daemon *d;
+
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG | poll_flag,
+                        1081, NULL, NULL, &ahc_echo, "GET",
+                        MHD_OPTION_THREAD_POOL_SIZE, CPU_COUNT, MHD_OPTION_END);
+  if (d == NULL)
+    return 4;
+  MHD_stop_daemon (d);
+  return 0;
+}
+
+static int
+testExternalGet ()
+{
+  struct MHD_Daemon *d;
+
+  d = MHD_start_daemon (MHD_USE_DEBUG,
+                        1082, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 8;
+  MHD_stop_daemon (d);
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  errorCount += testInternalGet (0);
+  errorCount += testMultithreadedGet (0);
+  errorCount += testMultithreadedPoolGet (0);
+  errorCount += testExternalGet ();
+  if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_POLL))
+    {
+      errorCount += testInternalGet(MHD_USE_POLL);
+      errorCount += testMultithreadedGet(MHD_USE_POLL);
+      errorCount += testMultithreadedPoolGet(MHD_USE_POLL);
+    }
+  if (MHD_YES == MHD_is_feature_supported(MHD_FEATURE_EPOLL))
+    {
+      errorCount += testInternalGet(MHD_USE_EPOLL_LINUX_ONLY);
+      errorCount += testMultithreadedPoolGet(MHD_USE_EPOLL_LINUX_ONLY);
+    }
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  return errorCount != 0;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_termination.c b/src/testcurl/test_termination.c
new file mode 100644
index 0000000..25f9e61
--- /dev/null
+++ b/src/testcurl/test_termination.c
@@ -0,0 +1,125 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2009 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file daemontest_termination.c
+ * @brief  Testcase for libmicrohttpd tolerating client not closing immediately
+ * @author hollosig
+ */
+#define PORT	12345
+
+#include "platform.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <microhttpd.h>
+#include <unistd.h>
+#include <curl/curl.h>
+
+#ifndef __MINGW32__
+#include <sys/select.h>
+#include <sys/socket.h>
+#endif
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif /* !WIN32_LEAN_AND_MEAN */
+#include <windows.h>
+#endif
+
+static int
+connection_handler (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 **ptr)
+{
+  static int i;
+
+  if (*ptr == NULL)
+    {
+      *ptr = &i;
+      return MHD_YES;
+    }
+
+  if (*upload_data_size != 0)
+    {
+      (*upload_data_size) = 0;
+      return MHD_YES;
+    }
+
+  struct MHD_Response *response =
+    MHD_create_response_from_buffer (strlen ("Response"), "Response",
+				     MHD_RESPMEM_PERSISTENT);
+  int ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+
+  return ret;
+}
+
+static size_t
+write_data (void *ptr, size_t size, size_t nmemb, void *stream)
+{
+  return size * nmemb;
+}
+
+int
+main ()
+{
+  struct MHD_Daemon *daemon;
+
+  daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
+                             PORT,
+                             NULL,
+                             NULL, connection_handler, NULL, MHD_OPTION_END);
+
+  if (daemon == NULL)
+    {
+      fprintf (stderr, "Daemon cannot be started!");
+      exit (1);
+    }
+
+  CURL *curl = curl_easy_init ();
+  //curl_easy_setopt(curl, CURLOPT_POST, 1L);
+  char url[255];
+  sprintf (url, "http://127.0.0.1:%d", PORT);
+  curl_easy_setopt (curl, CURLOPT_URL, url);
+  curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, write_data);
+
+  CURLcode success = curl_easy_perform (curl);
+  if (success != 0)
+    {
+      fprintf (stderr, "CURL Error");
+      exit (1);
+    }
+  /* CPU used to go crazy here */
+  sleep (1);
+
+  curl_easy_cleanup (curl);
+  MHD_stop_daemon (daemon);
+
+  return 0;
+}
diff --git a/src/testcurl/test_timeout.c b/src/testcurl/test_timeout.c
new file mode 100644
index 0000000..006c1a8
--- /dev/null
+++ b/src/testcurl/test_timeout.c
@@ -0,0 +1,294 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file test_timeout.c
+ * @brief  Testcase for libmicrohttpd PUT operations
+ * @author Matthias Wachs
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+static int oneone;
+
+static int withTimeout = 1;
+
+static int withoutTimeout = 1;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+
+static void 
+termination_cb (void *cls, 
+		struct MHD_Connection *connection, 
+		void **con_cls, 
+		enum MHD_RequestTerminationCode toe)
+{
+  int *test = cls;
+
+  switch (toe)
+    {
+    case MHD_REQUEST_TERMINATED_COMPLETED_OK :
+      if (test == &withoutTimeout)
+	{
+	  withoutTimeout = 0;
+	}
+      break;
+    case MHD_REQUEST_TERMINATED_WITH_ERROR :
+    case MHD_REQUEST_TERMINATED_READ_ERROR :
+      break;
+    case MHD_REQUEST_TERMINATED_TIMEOUT_REACHED :
+      if (test == &withTimeout)
+	{
+	  withTimeout = 0;
+	}
+      break;
+    case MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN:
+      break;
+    case MHD_REQUEST_TERMINATED_CLIENT_ABORT:
+      break;
+    }
+}
+
+
+static size_t
+putBuffer (void *stream, size_t size, size_t nmemb, void *ptr)
+{
+  unsigned int *pos = ptr;
+  unsigned int wrt;
+
+  wrt = size * nmemb;
+  if (wrt > 8 - (*pos))
+	wrt = 8 - (*pos);
+  memcpy (stream, &("Hello123"[*pos]), wrt);
+  (*pos) += wrt;
+  return wrt;
+}
+
+
+static size_t
+putBuffer_fail (void *stream, size_t size, size_t nmemb, void *ptr)
+{
+  return 0;
+}
+
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+
+static int
+ahc_echo (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)
+{
+  int *done = cls;
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 != strcmp ("PUT", method))
+    return MHD_NO;              /* unexpected method */
+  if ((*done) == 0)
+    {
+      if (*upload_data_size != 8)
+        return MHD_YES;         /* not yet ready */
+      if (0 == memcmp (upload_data, "Hello123", 8))
+        {
+          *upload_data_size = 0;
+        }
+      else
+        {
+          printf ("Invalid upload data `%8s'!\n", upload_data);
+          return MHD_NO;
+        }
+      *done = 1;
+      return MHD_YES;
+    }
+  response = MHD_create_response_from_buffer (strlen (url),
+					      (void *) url, 
+					      MHD_RESPMEM_MUST_COPY);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  return ret;
+}
+
+
+static int
+testWithoutTimeout ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  unsigned int pos = 0;
+  int done_flag = 0;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1080,
+                        NULL, NULL, &ahc_echo, &done_flag,
+                        MHD_OPTION_CONNECTION_TIMEOUT, 2,
+                        MHD_OPTION_NOTIFY_COMPLETED, &termination_cb, &withTimeout,
+                        MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+  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, 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, 150L);
+  // 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)))
+    {
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      return 2;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    return 4;
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 8;
+  return 0;
+}
+
+static int
+testWithTimeout ()
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  int done_flag = 0;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
+                        1080,
+                        NULL, NULL, &ahc_echo, &done_flag,
+                        MHD_OPTION_CONNECTION_TIMEOUT, 2,
+                        MHD_OPTION_NOTIFY_COMPLETED, &termination_cb, &withoutTimeout,
+                        MHD_OPTION_END);
+  if (d == NULL)
+    return 16;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
+  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
+  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
+  curl_easy_setopt (c, CURLOPT_READFUNCTION, &putBuffer_fail);
+  curl_easy_setopt (c, CURLOPT_READDATA, &testWithTimeout);
+  curl_easy_setopt (c, CURLOPT_UPLOAD, 1L);
+  curl_easy_setopt (c, CURLOPT_INFILESIZE_LARGE, (curl_off_t) 8L);
+  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, 150L);
+  // 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)))
+    {
+      curl_easy_cleanup (c);
+      MHD_stop_daemon (d);
+      if (errornum == CURLE_GOT_NOTHING)
+    	  /* mhd had the timeout */
+    	  return 0;
+      else
+    	  /* curl had the timeout first */
+    	  return 32;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  return 64;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 16;
+  errorCount += testWithoutTimeout ();
+  errorCount += testWithTimeout ();
+  if (errorCount != 0)
+    fprintf (stderr, 
+	     "Error during test execution (code: %u)\n",
+	     errorCount);
+  curl_global_cleanup ();
+  if ((withTimeout == 0) && (withoutTimeout == 0))
+    return 0;
+  else
+    return errorCount;       /* 0 == pass */
+}
diff --git a/src/testcurl/test_urlparse.c b/src/testcurl/test_urlparse.c
new file mode 100644
index 0000000..c48bff2
--- /dev/null
+++ b/src/testcurl/test_urlparse.c
@@ -0,0 +1,191 @@
+/*
+     This file is part of libmicrohttpd
+     Copyright (C) 2007, 2009, 2011 Christian Grothoff
+
+     libmicrohttpd is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 2, or (at your
+     option) any later version.
+
+     libmicrohttpd is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with libmicrohttpd; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file daemontest_urlparse.c
+ * @brief  Testcase for libmicrohttpd url parsing
+ * @author Christian Grothoff
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN 1
+#endif /* !WIN32_LEAN_AND_MEAN */
+#include <windows.h>
+#endif
+
+#ifndef WINDOWS
+#include <unistd.h>
+#include <sys/socket.h>
+#endif
+
+static int oneone;
+
+static int matches;
+
+struct CBC
+{
+  char *buf;
+  size_t pos;
+  size_t size;
+};
+
+static size_t
+copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
+{
+  struct CBC *cbc = ctx;
+
+  if (cbc->pos + size * nmemb > cbc->size)
+    return 0;                   /* overflow */
+  memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
+  cbc->pos += size * nmemb;
+  return size * nmemb;
+}
+
+static int 
+test_values (void *cls,
+	     enum MHD_ValueKind kind,
+	     const char *key,
+	     const char *value)
+{
+  if ( (0 == strcmp (key, "a")) &&
+       (0 == strcmp (value, "b")) )
+    matches += 1;
+  if ( (0 == strcmp (key, "c")) &&
+       (0 == strcmp (value, "")) )
+    matches += 2;
+  if ( (0 == strcmp (key, "d")) &&
+       (NULL == value) )
+    matches += 4;
+  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, size_t *upload_data_size,
+          void **unused)
+{
+  static int ptr;
+  const char *me = cls;
+  struct MHD_Response *response;
+  int ret;
+
+  if (0 != strcmp (me, method))
+    return MHD_NO;              /* unexpected method */
+  if (&ptr != *unused)
+    {
+      *unused = &ptr;
+      return MHD_YES;
+    }
+  MHD_get_connection_values (connection,
+			     MHD_GET_ARGUMENT_KIND,
+			     &test_values,
+			     NULL);
+  *unused = NULL;
+  response = MHD_create_response_from_buffer (strlen (url),
+					      (void *) url,
+					      MHD_RESPMEM_MUST_COPY);
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+  if (ret == MHD_NO)
+    abort ();
+  return ret;
+}
+
+
+static int
+testInternalGet (int poll_flag)
+{
+  struct MHD_Daemon *d;
+  CURL *c;
+  char buf[2048];
+  struct CBC cbc;
+  CURLcode errornum;
+
+  cbc.buf = buf;
+  cbc.size = 2048;
+  cbc.pos = 0;
+  d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG  | poll_flag,
+                        11080, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+  if (d == NULL)
+    return 1;
+  c = curl_easy_init ();
+  curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:11080/hello_world?a=b&c=&d");
+  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, 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 2;
+    }
+  curl_easy_cleanup (c);
+  MHD_stop_daemon (d);
+  if (cbc.pos != strlen ("/hello_world"))
+    return 4;
+  if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world")))
+    return 8;
+  if (matches != 7)
+    return 16;
+  return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  unsigned int errorCount = 0;
+
+  oneone = (NULL != strrchr (argv[0], (int) '/')) ?
+    (NULL != strstr (strrchr (argv[0], (int) '/'), "11")) : 0;
+  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+    return 2;
+  errorCount += testInternalGet (0);
+  if (errorCount != 0)
+    fprintf (stderr, "Error (code: %u)\n", errorCount);
+  curl_global_cleanup ();
+  return errorCount != 0;       /* 0 == pass */
+}