aboutsummaryrefslogtreecommitdiff
path: root/src/testcurl/https/tls_thread_mode_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testcurl/https/tls_thread_mode_test.c')
-rw-r--r--src/testcurl/https/tls_thread_mode_test.c326
1 files changed, 8 insertions, 318 deletions
diff --git a/src/testcurl/https/tls_thread_mode_test.c b/src/testcurl/https/tls_thread_mode_test.c
index 24882d95..cf92a26d 100644
--- a/src/testcurl/https/tls_thread_mode_test.c
+++ b/src/testcurl/https/tls_thread_mode_test.c
@@ -35,230 +35,12 @@
35#include "gnutls.h" 35#include "gnutls.h"
36#include <curl/curl.h> 36#include <curl/curl.h>
37 37
38#define DEBUG_CURL_VERBOSE 0 38#include "tls_test_common.h"
39#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>" 39extern const char srv_key_pem[];
40 40extern const char srv_self_signed_cert_pem[];
41#define MHD_E_MEM "Error: memory error\n"
42#define MHD_E_SERVER_INIT "Error: failed to start server\n"
43#define MHD_E_TEST_FILE_CREAT "Error: failed to setup test file\n"
44#define MHD_E_CERT_FILE_CREAT "Error: failed to setup test certificate\n"
45#define MHD_E_KEY_FILE_CREAT "Error: failed to setup test certificate\n"
46
47#include "tls_test_keys.h"
48
49const char *test_file_name = "https_test_file";
50const char test_file_data[] = "Hello World\n";
51 41
52int curl_check_version (const char *req_version, ...); 42int curl_check_version (const char *req_version, ...);
53 43
54struct CBC
55{
56 char *buf;
57 size_t pos;
58 size_t size;
59};
60
61struct https_test_data
62{
63 FILE *test_fd;
64 char *cipher_suite;
65 int proto_version;
66};
67
68struct CipherDef
69{
70 int options[2];
71 char *curlname;
72};
73
74static size_t
75copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
76{
77 struct CBC *cbc = ctx;
78
79 if (cbc->pos + size * nmemb > cbc->size)
80 return 0; /* overflow */
81 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
82 cbc->pos += size * nmemb;
83 return size * nmemb;
84}
85
86static int
87file_reader (void *cls, size_t pos, char *buf, int max)
88{
89 FILE *file = cls;
90 fseek (file, pos, SEEK_SET);
91 return fread (buf, 1, max, file);
92}
93
94/* HTTP access handler call back */
95static int
96http_ahc (void *cls, struct MHD_Connection *connection,
97 const char *url, const char *method, const char *upload_data,
98 const char *version, unsigned int *upload_data_size, void **ptr)
99{
100 static int aptr;
101 struct MHD_Response *response;
102 int ret;
103 FILE *file;
104 struct stat buf;
105
106 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
107 return MHD_NO; /* unexpected method */
108 if (&aptr != *ptr)
109 {
110 /* do never respond on first call */
111 *ptr = &aptr;
112 return MHD_YES;
113 }
114 *ptr = NULL; /* reset when done */
115
116 file = fopen (url, "r");
117 if (file == NULL)
118 {
119 response = MHD_create_response_from_data (strlen (PAGE_NOT_FOUND),
120 (void *) PAGE_NOT_FOUND,
121 MHD_NO, MHD_NO);
122 ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
123 MHD_destroy_response (response);
124 }
125 else
126 {
127 stat (url, &buf);
128 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
129 &file_reader, file,
130 (MHD_ContentReaderFreeCallback)
131 & fclose);
132 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
133 MHD_destroy_response (response);
134 }
135 return ret;
136}
137
138
139
140/**
141 * test HTTPS transfer
142 * @param test_fd: file to attempt transfering
143 */
144static int
145test_https_transfer (FILE * test_fd, char *cipher_suite, int proto_version)
146{
147 CURL *c;
148 CURLcode errornum;
149 struct CBC cbc;
150 char *doc_path;
151 size_t doc_path_len;
152 char url[255];
153 struct stat statb;
154
155 stat (test_file_name, &statb);
156
157 int len = statb.st_size;
158
159 /* used to memcmp local copy & deamon supplied copy */
160 unsigned char *mem_test_file_local;
161
162 /* setup test file path, url */
163 doc_path_len = PATH_MAX > 4096 ? 4096 : PATH_MAX;
164 if (NULL == (doc_path = malloc (doc_path_len)))
165 {
166 fprintf (stderr, MHD_E_MEM);
167 return -1;
168 }
169 if (getcwd (doc_path, doc_path_len) == NULL)
170 {
171 fprintf (stderr, "Error: failed to get working directory. %s\n",
172 strerror (errno));
173 free (doc_path);
174 return -1;
175 }
176
177 if (NULL == (mem_test_file_local = malloc (len)))
178 {
179 fprintf (stderr, MHD_E_MEM);
180 free (doc_path);
181 return -1;
182 }
183
184 fseek (test_fd, 0, SEEK_SET);
185 if (fread (mem_test_file_local, sizeof (char), len, test_fd) != len)
186 {
187 fprintf (stderr, "Error: failed to read test file. %s\n",
188 strerror (errno));
189 fclose (test_fd);
190 free (doc_path);
191 free (mem_test_file_local);
192 return -1;
193 }
194
195 if (NULL == (cbc.buf = malloc (len)))
196 {
197 free (doc_path);
198 free (mem_test_file_local);
199 fprintf (stderr, MHD_E_MEM);
200 return -1;
201 }
202 cbc.size = len;
203 cbc.pos = 0;
204
205 /* construct url - this might use doc_path */
206 sprintf (url, "%s%s/%s", "https://localhost:42433",
207 doc_path, test_file_name);
208
209 c = curl_easy_init ();
210#if DEBUG_CURL_VERBOSE
211 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
212#endif
213 curl_easy_setopt (c, CURLOPT_URL, url);
214 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
215 curl_easy_setopt (c, CURLOPT_TIMEOUT, 60L);
216 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 60L);
217 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
218 curl_easy_setopt (c, CURLOPT_FILE, &cbc);
219
220 /* TLS options */
221 curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version);
222 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
223
224 /* currently skip any peer authentication */
225 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
226 curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
227
228 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
229
230 /* NOTE: use of CONNECTTIMEOUT without also
231 setting NOSIGNAL results in really weird
232 crashes on my system! */
233 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
234 if (CURLE_OK != (errornum = curl_easy_perform (c)))
235 {
236 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
237 curl_easy_strerror (errornum));
238 curl_easy_cleanup (c);
239 free (cbc.buf);
240 free (mem_test_file_local);
241 free (doc_path);
242 return errornum;
243 }
244
245 curl_easy_cleanup (c);
246
247 if (memcmp (cbc.buf, mem_test_file_local, len) != 0)
248 {
249 fprintf (stderr, "Error: local file & received file differ.\n");
250 free (cbc.buf);
251 free (mem_test_file_local);
252 free (doc_path);
253 return -1;
254 }
255
256 free (mem_test_file_local);
257 free (cbc.buf);
258 free (doc_path);
259 return 0;
260}
261
262/** 44/**
263 * used when spawning multiple threads executing curl server requests 45 * used when spawning multiple threads executing curl server requests
264 * 46 *
@@ -279,92 +61,6 @@ https_transfer_thread_adapter (void *args)
279 return &nonnull; 61 return &nonnull;
280} 62}
281 63
282static FILE *
283setupTestFile ()
284{
285 FILE *test_fd;
286
287 if (NULL == (test_fd = fopen (test_file_name, "w+")))
288 {
289 fprintf (stderr, "Error: failed to open `%s': %s\n",
290 test_file_name, strerror (errno));
291 return NULL;
292 }
293 if (fwrite (test_file_data, sizeof (char), strlen (test_file_data), test_fd)
294 != strlen (test_file_data))
295 {
296 fprintf (stderr, "Error: failed to write `%s. %s'\n",
297 test_file_name, strerror (errno));
298 fclose (test_fd);
299 return NULL;
300 }
301 if (fflush (test_fd))
302 {
303 fprintf (stderr, "Error: failed to flush test file stream. %s\n",
304 strerror (errno));
305 fclose (test_fd);
306 return NULL;
307 }
308
309 return test_fd;
310}
311
312static int
313setup (struct MHD_Daemon **d, int daemon_flags, va_list arg_list)
314{
315 *d = MHD_start_daemon_va (daemon_flags, 42433,
316 NULL, NULL, &http_ahc, NULL, arg_list);
317
318 if (*d == NULL)
319 {
320 fprintf (stderr, MHD_E_SERVER_INIT);
321 return -1;
322 }
323
324 return 0;
325}
326
327static void
328teardown (struct MHD_Daemon *d)
329{
330 MHD_stop_daemon (d);
331}
332
333/* TODO test_wrap: change sig to (setup_func, test, va_list test_arg) & move to test_util.c */
334static int
335test_wrap (char *test_name, int
336 (*test_function) (FILE * test_fd, char *cipher_suite,
337 int proto_version), FILE * test_fd,
338 int daemon_flags, char *cipher_suite, int proto_version, ...)
339{
340 int ret;
341 va_list arg_list;
342 struct MHD_Daemon *d;
343
344 va_start (arg_list, proto_version);
345 if (setup (&d, daemon_flags, arg_list) != 0)
346 {
347 va_end (arg_list);
348 return -1;
349 }
350
351 fprintf (stdout, "running test: %s ", test_name);
352 ret = test_function (test_fd, cipher_suite, proto_version);
353
354 if (ret == 0)
355 {
356 fprintf (stdout, "[pass]\n");
357 }
358 else
359 {
360 fprintf (stdout, "[fail]\n");
361 }
362
363 teardown (d);
364 va_end (arg_list);
365 return ret;
366}
367
368/** 64/**
369 * Test non-parallel requests. 65 * Test non-parallel requests.
370 * 66 *
@@ -386,7 +82,6 @@ test_single_client (FILE * test_fd, char *cipher_suite,
386 return 0; 82 return 0;
387} 83}
388 84
389
390/** 85/**
391 * Test parallel request handling. 86 * Test parallel request handling.
392 * 87 *
@@ -408,11 +103,9 @@ test_parallel_clients (FILE * test_fd, char *cipher_suite,
408 for (i = 0; i < client_count; ++i) 103 for (i = 0; i < client_count; ++i)
409 { 104 {
410 if (pthread_create (&client_arr[i], NULL, 105 if (pthread_create (&client_arr[i], NULL,
411 &https_transfer_thread_adapter, 106 &https_transfer_thread_adapter, &client_args) != 0)
412 &client_args) != 0)
413 { 107 {
414 fprintf (stderr, "Error: failed to spawn test client threads.\n"); 108 fprintf (stderr, "Error: failed to spawn test client threads.\n");
415
416 return -1; 109 return -1;
417 } 110 }
418 } 111 }
@@ -428,7 +121,6 @@ test_parallel_clients (FILE * test_fd, char *cipher_suite,
428 return 0; 121 return 0;
429} 122}
430 123
431
432int 124int
433main (int argc, char *const *argv) 125main (int argc, char *const *argv)
434{ 126{
@@ -442,7 +134,7 @@ main (int argc, char *const *argv)
442 if (curl_check_version (MHD_REQ_CURL_VERSION)) 134 if (curl_check_version (MHD_REQ_CURL_VERSION))
443 return -1; 135 return -1;
444 136
445 if ((test_fd = setupTestFile ()) == NULL) 137 if ((test_fd = setup_test_file ()) == NULL)
446 { 138 {
447 fprintf (stderr, MHD_E_TEST_FILE_CREAT); 139 fprintf (stderr, MHD_E_TEST_FILE_CREAT);
448 return -1; 140 return -1;
@@ -452,6 +144,7 @@ main (int argc, char *const *argv)
452 { 144 {
453 fprintf (stderr, "Error: %s\n", strerror (errno)); 145 fprintf (stderr, "Error: %s\n", strerror (errno));
454 fclose (test_fd); 146 fclose (test_fd);
147 remove (TEST_FILE_NAME);
455 return -1; 148 return -1;
456 } 149 }
457 150
@@ -462,6 +155,7 @@ main (int argc, char *const *argv)
462 "AES256-SHA", CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY, 155 "AES256-SHA", CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
463 srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT, 156 srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
464 srv_self_signed_cert_pem, MHD_OPTION_END); 157 srv_self_signed_cert_pem, MHD_OPTION_END);
158
465 errorCount += 159 errorCount +=
466 test_wrap ("single threaded daemon, parallel clients", 160 test_wrap ("single threaded daemon, parallel clients",
467 &test_parallel_clients, test_fd, 161 &test_parallel_clients, test_fd,
@@ -470,13 +164,9 @@ main (int argc, char *const *argv)
470 srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT, 164 srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
471 srv_self_signed_cert_pem, MHD_OPTION_END); 165 srv_self_signed_cert_pem, MHD_OPTION_END);
472 166
473 if (errorCount != 0)
474 fprintf (stderr, "Failed test: %s.\n", argv[0]);
475
476 curl_global_cleanup (); 167 curl_global_cleanup ();
477 fclose (test_fd); 168 fclose (test_fd);
478 169 remove (TEST_FILE_NAME);
479 remove (test_file_name);
480 170
481 return errorCount != 0; 171 return errorCount != 0;
482} 172}