libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 26ed57fcf987edd4c641477d52e2f9d386bedf43
parent f6d108e3bced2a30237543c8054d776ebe34689d
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon,  4 Mar 2013 13:42:40 +0000

testcase for #2783

Diffstat:
Msrc/testcurl/https/Makefile.am | 14++++++++++++--
Msrc/testcurl/https/mhds_get_test_select.c | 1-
Asrc/testcurl/https/test_empty_response.c | 205+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 217 insertions(+), 3 deletions(-)

diff --git a/src/testcurl/https/Makefile.am b/src/testcurl/https/Makefile.am @@ -23,7 +23,8 @@ check_PROGRAMS = \ mhds_session_info_test \ tls_thread_mode_test \ tls_multi_thread_mode_test \ - tls_session_time_out_test + tls_session_time_out_test \ + test_empty_response EXTRA_DIST = cert.pem key.pem tls_test_keys.h tls_test_common.h @@ -37,7 +38,8 @@ TESTS = \ tls_thread_mode_test \ tls_multi_thread_mode_test \ tls_session_time_out_test \ - tls_authentication_test + tls_authentication_test \ + test_empty_response # cURL dependent tests tls_session_time_out_test_SOURCES = \ @@ -64,6 +66,14 @@ tls_thread_mode_test_LDADD = \ $(top_builddir)/src/daemon/libmicrohttpd.la \ @LIBCURL@ -lgnutls @LIBGCRYPT_LIBS@ +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/daemon/libmicrohttpd.la \ + @LIBCURL@ -lgnutls @LIBGCRYPT_LIBS@ + tls_multi_thread_mode_test_SOURCES = \ tls_multi_thread_mode_test.c \ tls_test_common.c diff --git a/src/testcurl/https/mhds_get_test_select.c b/src/testcurl/https/mhds_get_test_select.c @@ -151,7 +151,6 @@ testExternalGet () 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) { diff --git a/src/testcurl/https/test_empty_response.c b/src/testcurl/https/test_empty_response.c @@ -0,0 +1,205 @@ +/* + This file is part of libmicrohttpd + (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; + int 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_SSLv3); + 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; +} + +GCRY_THREAD_OPTION_PTHREAD_IMPL; + +int +main (int argc, char *const *argv) +{ + unsigned int errorCount = 0; + + gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); + if (!gcry_check_version (GCRYPT_VERSION)) + abort (); + 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; +}