diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-09-27 17:44:21 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2023-09-27 17:44:21 +0300 |
commit | 78e28ecca82bafbe4569c8e9c5307853a4a8dbdf (patch) | |
tree | 1b9081869cc876ec47c42db6b8e2c0d718b5b6f6 | |
parent | b1f2ddbb0310369519ff0dc2f0aa760323a4f674 (diff) | |
download | libmicrohttpd-78e28ecca82bafbe4569c8e9c5307853a4a8dbdf.tar.gz libmicrohttpd-78e28ecca82bafbe4569c8e9c5307853a4a8dbdf.zip |
test_long_header: improved, fixed, added error reporting
-rw-r--r-- | src/testcurl/test_long_header.c | 470 |
1 files changed, 339 insertions, 131 deletions
diff --git a/src/testcurl/test_long_header.c b/src/testcurl/test_long_header.c index 30744934..15469147 100644 --- a/src/testcurl/test_long_header.c +++ b/src/testcurl/test_long_header.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of libmicrohttpd | 2 | This file is part of libmicrohttpd |
3 | Copyright (C) 2007 Christian Grothoff | 3 | Copyright (C) 2007 Christian Grothoff |
4 | Copyright (C) 2016-2022 Evgeny Grin (Karlson2k) | 4 | Copyright (C) 2016-2023 Evgeny Grin (Karlson2k) |
5 | 5 | ||
6 | libmicrohttpd is free software; you can redistribute it and/or modify | 6 | libmicrohttpd is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published | 7 | it under the terms of the GNU General Public License as published |
@@ -26,11 +26,12 @@ | |||
26 | * @author Karlson2k (Evgeny Grin) | 26 | * @author Karlson2k (Evgeny Grin) |
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include "MHD_config.h" | 29 | #include "mhd_options.h" |
30 | #include "platform.h" | 30 | #include "platform.h" |
31 | #include <curl/curl.h> | 31 | #include <curl/curl.h> |
32 | #include <microhttpd.h> | 32 | #include <microhttpd.h> |
33 | #include <stdlib.h> | 33 | #include <stdlib.h> |
34 | #include <stdio.h> | ||
34 | #include <string.h> | 35 | #include <string.h> |
35 | #include <time.h> | 36 | #include <time.h> |
36 | #include "mhd_has_in_name.h" | 37 | #include "mhd_has_in_name.h" |
@@ -39,6 +40,21 @@ | |||
39 | #include <unistd.h> | 40 | #include <unistd.h> |
40 | #endif | 41 | #endif |
41 | 42 | ||
43 | #ifndef MHD_STATICSTR_LEN_ | ||
44 | /** | ||
45 | * Determine length of static string / macro strings at compile time. | ||
46 | */ | ||
47 | #define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1) | ||
48 | #endif /* ! MHD_STATICSTR_LEN_ */ | ||
49 | |||
50 | #ifndef CURL_VERSION_BITS | ||
51 | #define CURL_VERSION_BITS(x,y,z) ((x) << 16 | (y) << 8 | (z)) | ||
52 | #endif /* ! CURL_VERSION_BITS */ | ||
53 | #ifndef CURL_AT_LEAST_VERSION | ||
54 | #define CURL_AT_LEAST_VERSION(x,y,z) \ | ||
55 | (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS (x, y, z)) | ||
56 | #endif /* ! CURL_AT_LEAST_VERSION */ | ||
57 | |||
42 | /** | 58 | /** |
43 | * We will set the memory available per connection to | 59 | * We will set the memory available per connection to |
44 | * half of this value, so the actual value does not have | 60 | * half of this value, so the actual value does not have |
@@ -46,17 +62,24 @@ | |||
46 | */ | 62 | */ |
47 | #define VERY_LONG (1024 * 8) | 63 | #define VERY_LONG (1024 * 8) |
48 | 64 | ||
65 | /* Could be increased to facilitate debugging */ | ||
66 | #define TIMEOUTS_VAL 5 | ||
67 | |||
68 | #define EXPECTED_URI_BASE_PATH "/" | ||
69 | |||
70 | #define URL_SCHEME "http:/" "/" | ||
71 | |||
72 | #define URL_HOST "127.0.0.1" | ||
73 | |||
74 | #define URL_SCHEME_HOST_PATH URL_SCHEME URL_HOST EXPECTED_URI_BASE_PATH | ||
75 | |||
76 | |||
49 | static int oneone; | 77 | static int oneone; |
50 | 78 | ||
51 | static uint16_t daemon_port; | 79 | static uint16_t daemon_port; |
52 | 80 | ||
53 | static enum MHD_Result | ||
54 | apc_all (void *cls, const struct sockaddr *addr, socklen_t addrlen) | ||
55 | { | ||
56 | (void) cls; (void) addr; (void) addrlen; /* Unused. Silent compiler warning. */ | ||
57 | return MHD_YES; | ||
58 | } | ||
59 | 81 | ||
82 | static char libcurl_err_buf[CURL_ERROR_SIZE]; | ||
60 | 83 | ||
61 | struct CBC | 84 | struct CBC |
62 | { | 85 | { |
@@ -73,6 +96,132 @@ copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx) | |||
73 | } | 96 | } |
74 | 97 | ||
75 | 98 | ||
99 | /* Return non-zero on success, zero on failure */ | ||
100 | static int | ||
101 | setup_easy_handler_params (CURL *c, struct CBC *pcbc, const char *url, | ||
102 | struct curl_slist *header) | ||
103 | { | ||
104 | libcurl_err_buf[0] = 0; /* Reset error message */ | ||
105 | |||
106 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_ERRORBUFFER, libcurl_err_buf)) | ||
107 | { | ||
108 | fprintf (stderr, "Failed to set CURLOPT_ERRORBUFFER option.\n"); | ||
109 | return 0; | ||
110 | } | ||
111 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L)) | ||
112 | { | ||
113 | fprintf (stderr, "Failed to set CURLOPT_NOSIGNAL option.\n"); | ||
114 | return 0; | ||
115 | } | ||
116 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, | ||
117 | ©Buffer)) | ||
118 | { | ||
119 | fprintf (stderr, "Failed to set CURLOPT_WRITEFUNCTION option.\n"); | ||
120 | return 0; | ||
121 | } | ||
122 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEDATA, pcbc)) | ||
123 | { | ||
124 | fprintf (stderr, "Failed to set CURLOPT_WRITEDATA option.\n"); | ||
125 | return 0; | ||
126 | } | ||
127 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, | ||
128 | ((long) TIMEOUTS_VAL))) | ||
129 | { | ||
130 | fprintf (stderr, "Failed to set CURLOPT_CONNECTTIMEOUT option.\n"); | ||
131 | return 0; | ||
132 | } | ||
133 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_TIMEOUT, | ||
134 | ((long) TIMEOUTS_VAL))) | ||
135 | { | ||
136 | fprintf (stderr, "Failed to set CURLOPT_TIMEOUT option.\n"); | ||
137 | return 0; | ||
138 | } | ||
139 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION, | ||
140 | (oneone) ? | ||
141 | CURL_HTTP_VERSION_1_1 : | ||
142 | CURL_HTTP_VERSION_1_0)) | ||
143 | { | ||
144 | fprintf (stderr, "Failed to set CURLOPT_HTTP_VERSION option.\n"); | ||
145 | return 0; | ||
146 | } | ||
147 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_FAILONERROR, 0L)) | ||
148 | { | ||
149 | fprintf (stderr, "Failed to set CURLOPT_FAILONERROR option.\n"); | ||
150 | return 0; | ||
151 | } | ||
152 | #ifdef _DEBUG | ||
153 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_VERBOSE, 1L)) | ||
154 | { | ||
155 | fprintf (stderr, "Failed to set CURLOPT_VERBOSE option.\n"); | ||
156 | return 0; | ||
157 | } | ||
158 | #endif /* _DEBUG */ | ||
159 | #if CURL_AT_LEAST_VERSION (7, 45, 0) | ||
160 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_DEFAULT_PROTOCOL, "http")) | ||
161 | { | ||
162 | fprintf (stderr, "Failed to set CURLOPT_DEFAULT_PROTOCOL option.\n"); | ||
163 | return 0; | ||
164 | } | ||
165 | #endif /* CURL_AT_LEAST_VERSION (7, 45, 0) */ | ||
166 | #if CURL_AT_LEAST_VERSION (7, 85, 0) | ||
167 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_PROTOCOLS_STR, "http")) | ||
168 | { | ||
169 | fprintf (stderr, "Failed to set CURLOPT_PROTOCOLS_STR option.\n"); | ||
170 | return 0; | ||
171 | } | ||
172 | #elif CURL_AT_LEAST_VERSION (7, 19, 4) | ||
173 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP)) | ||
174 | { | ||
175 | fprintf (stderr, "Failed to set CURLOPT_PROTOCOLS option.\n"); | ||
176 | return 0; | ||
177 | } | ||
178 | #endif /* CURL_AT_LEAST_VERSION (7, 19, 4) */ | ||
179 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_URL, | ||
180 | (NULL != url) ? | ||
181 | url : URL_SCHEME_HOST_PATH)) | ||
182 | { | ||
183 | fprintf (stderr, "Failed to set CURLOPT_PROTOCOLS option.\n"); | ||
184 | return 0; | ||
185 | } | ||
186 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, ((long) daemon_port))) | ||
187 | { | ||
188 | fprintf (stderr, "Failed to set CURLOPT_PROTOCOLS option.\n"); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | if (NULL != header) | ||
193 | { | ||
194 | if (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTPHEADER, header)) | ||
195 | { | ||
196 | fprintf (stderr, "Failed to set CURLOPT_HTTPHEADER option.\n"); | ||
197 | return 0; | ||
198 | } | ||
199 | } | ||
200 | return ! 0; | ||
201 | } | ||
202 | |||
203 | |||
204 | static CURL * | ||
205 | setup_easy_handler (struct CBC *pcbc, const char *url, struct | ||
206 | curl_slist *header) | ||
207 | { | ||
208 | CURL *c; | ||
209 | |||
210 | c = curl_easy_init (); | ||
211 | if (NULL == c) | ||
212 | { | ||
213 | fprintf (stderr, "curl_easy_init() error.\n"); | ||
214 | return NULL; | ||
215 | } | ||
216 | if (setup_easy_handler_params (c, pcbc, url, header)) | ||
217 | { | ||
218 | return c; /* Success exit point */ | ||
219 | } | ||
220 | curl_easy_cleanup (c); | ||
221 | return NULL; | ||
222 | } | ||
223 | |||
224 | |||
76 | static enum MHD_Result | 225 | static enum MHD_Result |
77 | ahc_echo (void *cls, | 226 | ahc_echo (void *cls, |
78 | struct MHD_Connection *connection, | 227 | struct MHD_Connection *connection, |
@@ -84,10 +233,17 @@ ahc_echo (void *cls, | |||
84 | { | 233 | { |
85 | struct MHD_Response *response; | 234 | struct MHD_Response *response; |
86 | enum MHD_Result ret; | 235 | enum MHD_Result ret; |
236 | static int marker; | ||
237 | |||
87 | (void) cls; | 238 | (void) cls; |
88 | (void) version; (void) upload_data; /* Unused. Silent compiler warning. */ | 239 | (void) version; (void) upload_data; /* Unused. Silent compiler warning. */ |
89 | (void) upload_data_size; (void) req_cls; /* Unused. Silent compiler warning. */ | 240 | (void) upload_data_size; (void) req_cls; /* Unused. Silent compiler warning. */ |
90 | 241 | ||
242 | if (&marker != *req_cls) | ||
243 | { | ||
244 | *req_cls = ▮ | ||
245 | return MHD_YES; | ||
246 | } | ||
91 | if (0 != strcmp (MHD_HTTP_METHOD_GET, method)) | 247 | if (0 != strcmp (MHD_HTTP_METHOD_GET, method)) |
92 | return MHD_NO; /* unexpected method */ | 248 | return MHD_NO; /* unexpected method */ |
93 | response = MHD_create_response_from_buffer_copy (strlen (url), | 249 | response = MHD_create_response_from_buffer_copy (strlen (url), |
@@ -102,81 +258,106 @@ static unsigned int | |||
102 | testLongUrlGet (size_t buff_size) | 258 | testLongUrlGet (size_t buff_size) |
103 | { | 259 | { |
104 | struct MHD_Daemon *d; | 260 | struct MHD_Daemon *d; |
105 | CURL *c; | 261 | unsigned int ret; |
106 | char buf[2048]; | 262 | |
107 | struct CBC cbc; | 263 | ret = 1; /* Error value, shall be reset to zero if succeed */ |
108 | char *url; | ||
109 | long code; | ||
110 | |||
111 | cbc.buf = buf; | ||
112 | cbc.size = 2048; | ||
113 | cbc.pos = 0; | ||
114 | d = | 264 | d = |
115 | MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */, | 265 | MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */, |
116 | daemon_port, | 266 | daemon_port, |
117 | &apc_all, | 267 | NULL, |
118 | NULL, | 268 | NULL, |
119 | &ahc_echo, NULL, | 269 | &ahc_echo, NULL, |
120 | MHD_OPTION_CONNECTION_MEMORY_LIMIT, | 270 | MHD_OPTION_CONNECTION_MEMORY_LIMIT, |
121 | (size_t) buff_size, MHD_OPTION_END); | 271 | (size_t) buff_size, MHD_OPTION_END); |
122 | if (d == NULL) | 272 | if (d == NULL) |
123 | return 1; | 273 | { |
274 | fprintf (stderr, "MHD_start_daemon() failed.\n"); | ||
275 | return 16; | ||
276 | } | ||
124 | if (0 == daemon_port) | 277 | if (0 == daemon_port) |
125 | { | 278 | { |
126 | const union MHD_DaemonInfo *dinfo; | 279 | const union MHD_DaemonInfo *dinfo; |
127 | dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); | 280 | dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); |
128 | if ((NULL == dinfo) || (0 == dinfo->port) ) | 281 | if ((NULL == dinfo) || (0 == dinfo->port) ) |
129 | { | 282 | fprintf (stderr, "MHD_get_daemon_info(d, MHD_DAEMON_INFO_BIND_PORT) " \ |
130 | MHD_stop_daemon (d); return 32; | 283 | "failed.\n"); |
131 | } | 284 | else |
132 | daemon_port = dinfo->port; | 285 | daemon_port = dinfo->port; |
133 | } | ||
134 | c = curl_easy_init (); | ||
135 | url = malloc (VERY_LONG); | ||
136 | if (NULL == url) | ||
137 | { | ||
138 | curl_easy_cleanup (c); | ||
139 | MHD_stop_daemon (d); | ||
140 | return 1; | ||
141 | } | ||
142 | memset (url, 'a', VERY_LONG); | ||
143 | url[VERY_LONG - 1] = '\0'; | ||
144 | memcpy (url, "http://127.0.0.1/", strlen ("http://127.0.0.1/")); | ||
145 | curl_easy_setopt (c, CURLOPT_URL, url); | ||
146 | curl_easy_setopt (c, CURLOPT_PORT, (long) daemon_port); | ||
147 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); | ||
148 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); | ||
149 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 0L); | ||
150 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L); | ||
151 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L); | ||
152 | if (oneone) | ||
153 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); | ||
154 | else | ||
155 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); | ||
156 | /* NOTE: use of CONNECTTIMEOUT without also | ||
157 | setting NOSIGNAL results in really weird | ||
158 | crashes on my system! */ | ||
159 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L); | ||
160 | if (CURLE_OK != curl_easy_perform (c)) | ||
161 | { | ||
162 | curl_easy_cleanup (c); | ||
163 | MHD_stop_daemon (d); | ||
164 | free (url); | ||
165 | return 2; | ||
166 | } | 286 | } |
167 | if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code)) | 287 | if (0 != daemon_port) |
168 | { | 288 | { |
169 | curl_easy_cleanup (c); | 289 | char *url_str; |
170 | MHD_stop_daemon (d); | 290 | url_str = malloc (VERY_LONG); |
171 | free (url); | 291 | if (NULL == url_str) |
172 | return 4; | 292 | fprintf (stderr, "malloc (VERY_LONG) failed.\n"); |
293 | else | ||
294 | { | ||
295 | CURL *c; | ||
296 | char buf[2048]; | ||
297 | struct CBC cbc; | ||
298 | |||
299 | memset (url_str, 'a', VERY_LONG); | ||
300 | url_str[VERY_LONG - 1] = '\0'; | ||
301 | memcpy (url_str, URL_SCHEME_HOST_PATH, | ||
302 | MHD_STATICSTR_LEN_ (URL_SCHEME_HOST_PATH)); | ||
303 | |||
304 | cbc.buf = buf; | ||
305 | cbc.size = sizeof (buf); | ||
306 | cbc.pos = 0; | ||
307 | |||
308 | c = setup_easy_handler (&cbc, url_str, NULL); | ||
309 | if (NULL != c) | ||
310 | { | ||
311 | CURLcode r; | ||
312 | r = curl_easy_perform (c); | ||
313 | if (CURLE_OK != r) | ||
314 | { | ||
315 | fprintf (stderr, "curl_easy_perform() failed. Error message: %s\n", | ||
316 | curl_easy_strerror (r)); | ||
317 | if (0 != libcurl_err_buf[0]) | ||
318 | fprintf (stderr, "Detailed error message: %s\n", libcurl_err_buf); | ||
319 | } | ||
320 | else | ||
321 | { | ||
322 | long code; | ||
323 | |||
324 | r = curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code); | ||
325 | if (CURLE_OK != r) | ||
326 | { | ||
327 | fprintf (stderr, "curl_easy_getinfo() failed. " | ||
328 | "Error message: %s\n", | ||
329 | curl_easy_strerror (r)); | ||
330 | if (0 != libcurl_err_buf[0]) | ||
331 | fprintf (stderr, "Detailed error message: %s\n", | ||
332 | libcurl_err_buf); | ||
333 | } | ||
334 | else | ||
335 | { | ||
336 | if (code != MHD_HTTP_URI_TOO_LONG) | ||
337 | { | ||
338 | fprintf (stderr, "testLongHeaderGet(%lu) failed. HTTP " | ||
339 | "response code is %ld, while it should be %ld.\n", | ||
340 | (unsigned long) buff_size, | ||
341 | code, | ||
342 | (long) MHD_HTTP_URI_TOO_LONG); | ||
343 | } | ||
344 | else | ||
345 | { | ||
346 | printf ("testLongHeaderGet(%lu) succeed. HTTP " | ||
347 | "response code is %ld, as expected.\n", | ||
348 | (unsigned long) buff_size, | ||
349 | (long) MHD_HTTP_URI_TOO_LONG); | ||
350 | ret = 0; /* Success */ | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | curl_easy_cleanup (c); | ||
355 | } | ||
356 | free (url_str); | ||
357 | } | ||
173 | } | 358 | } |
174 | curl_easy_cleanup (c); | ||
175 | MHD_stop_daemon (d); | 359 | MHD_stop_daemon (d); |
176 | free (url); | 360 | return ret; |
177 | if (code != MHD_HTTP_URI_TOO_LONG) | ||
178 | return 8; | ||
179 | return 0; | ||
180 | } | 361 | } |
181 | 362 | ||
182 | 363 | ||
@@ -184,89 +365,115 @@ static unsigned int | |||
184 | testLongHeaderGet (size_t buff_size) | 365 | testLongHeaderGet (size_t buff_size) |
185 | { | 366 | { |
186 | struct MHD_Daemon *d; | 367 | struct MHD_Daemon *d; |
187 | CURL *c; | 368 | unsigned int ret; |
188 | char buf[2048]; | 369 | |
189 | struct CBC cbc; | 370 | ret = 1; /* Error value, shall be reset to zero if succeed */ |
190 | char *url; | ||
191 | long code; | ||
192 | struct curl_slist *header = NULL; | ||
193 | |||
194 | cbc.buf = buf; | ||
195 | cbc.size = 2048; | ||
196 | cbc.pos = 0; | ||
197 | d = | 371 | d = |
198 | MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */, | 372 | MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD /* | MHD_USE_ERROR_LOG */, |
199 | daemon_port, | 373 | daemon_port, |
200 | &apc_all, | 374 | NULL, |
201 | NULL, | 375 | NULL, |
202 | &ahc_echo, NULL, | 376 | &ahc_echo, NULL, |
203 | MHD_OPTION_CONNECTION_MEMORY_LIMIT, | 377 | MHD_OPTION_CONNECTION_MEMORY_LIMIT, |
204 | (size_t) buff_size, MHD_OPTION_END); | 378 | (size_t) buff_size, MHD_OPTION_END); |
205 | if (d == NULL) | 379 | if (d == NULL) |
380 | { | ||
381 | fprintf (stderr, "MHD_start_daemon() failed.\n"); | ||
206 | return 16; | 382 | return 16; |
383 | } | ||
207 | if (0 == daemon_port) | 384 | if (0 == daemon_port) |
208 | { | 385 | { |
209 | const union MHD_DaemonInfo *dinfo; | 386 | const union MHD_DaemonInfo *dinfo; |
210 | dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); | 387 | dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); |
211 | if ((NULL == dinfo) || (0 == dinfo->port) ) | 388 | if ((NULL == dinfo) || (0 == dinfo->port) ) |
212 | { | 389 | fprintf (stderr, "MHD_get_daemon_info(d, MHD_DAEMON_INFO_BIND_PORT) " \ |
213 | MHD_stop_daemon (d); return 32; | 390 | "failed.\n"); |
214 | } | 391 | else |
215 | daemon_port = dinfo->port; | 392 | daemon_port = dinfo->port; |
216 | } | ||
217 | c = curl_easy_init (); | ||
218 | url = malloc (VERY_LONG); | ||
219 | if (NULL == url) | ||
220 | { | ||
221 | curl_easy_cleanup (c); | ||
222 | MHD_stop_daemon (d); | ||
223 | return 16; | ||
224 | } | ||
225 | memset (url, 'a', VERY_LONG); | ||
226 | url[VERY_LONG - 1] = '\0'; | ||
227 | url[VERY_LONG / 2] = ':'; | ||
228 | url[VERY_LONG / 2 + 1] = ' '; | ||
229 | header = curl_slist_append (header, url); | ||
230 | |||
231 | curl_easy_setopt (c, CURLOPT_HTTPHEADER, header); | ||
232 | curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world"); | ||
233 | curl_easy_setopt (c, CURLOPT_PORT, (long) daemon_port); | ||
234 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); | ||
235 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); | ||
236 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 0L); | ||
237 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L); | ||
238 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L); | ||
239 | if (oneone) | ||
240 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); | ||
241 | else | ||
242 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); | ||
243 | /* NOTE: use of CONNECTTIMEOUT without also | ||
244 | setting NOSIGNAL results in really weird | ||
245 | crashes on my system! */ | ||
246 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L); | ||
247 | if (CURLE_OK != curl_easy_perform (c)) | ||
248 | { | ||
249 | curl_easy_cleanup (c); | ||
250 | MHD_stop_daemon (d); | ||
251 | curl_slist_free_all (header); | ||
252 | free (url); | ||
253 | return 32; | ||
254 | } | 393 | } |
255 | if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code)) | 394 | if (0 != daemon_port) |
256 | { | 395 | { |
257 | curl_slist_free_all (header); | 396 | char *header_str; |
258 | curl_easy_cleanup (c); | 397 | header_str = malloc (VERY_LONG); |
259 | MHD_stop_daemon (d); | 398 | if (NULL == header_str) |
260 | free (url); | 399 | fprintf (stderr, "malloc (VERY_LONG) failed.\n"); |
261 | return 64; | 400 | else |
401 | { | ||
402 | struct curl_slist *header = NULL; | ||
403 | |||
404 | memset (header_str, 'a', VERY_LONG); | ||
405 | header_str[VERY_LONG - 1] = '\0'; | ||
406 | header_str[VERY_LONG / 2] = ':'; | ||
407 | header_str[VERY_LONG / 2 + 1] = ' '; | ||
408 | |||
409 | header = curl_slist_append (header, header_str); | ||
410 | if (NULL == header) | ||
411 | fprintf (stderr, "curl_slist_append () failed.\n"); | ||
412 | else | ||
413 | { | ||
414 | CURL *c; | ||
415 | char buf[2048]; | ||
416 | struct CBC cbc; | ||
417 | |||
418 | cbc.buf = buf; | ||
419 | cbc.size = sizeof (buf); | ||
420 | cbc.pos = 0; | ||
421 | |||
422 | c = setup_easy_handler (&cbc, NULL, header); | ||
423 | if (NULL != c) | ||
424 | { | ||
425 | CURLcode r; | ||
426 | r = curl_easy_perform (c); | ||
427 | if (CURLE_OK != r) | ||
428 | { | ||
429 | fprintf (stderr, "curl_easy_perform() failed. Error message: %s\n", | ||
430 | curl_easy_strerror (r)); | ||
431 | if (0 != libcurl_err_buf[0]) | ||
432 | fprintf (stderr, "Detailed error message: %s\n", libcurl_err_buf); | ||
433 | } | ||
434 | else | ||
435 | { | ||
436 | long code; | ||
437 | |||
438 | r = curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code); | ||
439 | if (CURLE_OK != r) | ||
440 | { | ||
441 | fprintf (stderr, "curl_easy_getinfo() failed. " | ||
442 | "Error message: %s\n", | ||
443 | curl_easy_strerror (r)); | ||
444 | if (0 != libcurl_err_buf[0]) | ||
445 | fprintf (stderr, "Detailed error message: %s\n", | ||
446 | libcurl_err_buf); | ||
447 | } | ||
448 | else | ||
449 | { | ||
450 | if (code != MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE) | ||
451 | { | ||
452 | fprintf (stderr, "testLongHeaderGet(%lu) failed. HTTP " | ||
453 | "response code is %ld, while it should be %ld.\n", | ||
454 | (unsigned long) buff_size, | ||
455 | code, | ||
456 | (long) MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE); | ||
457 | } | ||
458 | else | ||
459 | { | ||
460 | printf ("testLongHeaderGet(%lu) succeed. HTTP " | ||
461 | "response code is %ld, as expected.\n", | ||
462 | (unsigned long) buff_size, | ||
463 | (long) MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE); | ||
464 | ret = 0; /* Success */ | ||
465 | } | ||
466 | } | ||
467 | } | ||
468 | curl_easy_cleanup (c); | ||
469 | } | ||
470 | curl_slist_free_all (header); | ||
471 | } | ||
472 | free (header_str); | ||
473 | } | ||
262 | } | 474 | } |
263 | curl_slist_free_all (header); | ||
264 | curl_easy_cleanup (c); | ||
265 | MHD_stop_daemon (d); | 475 | MHD_stop_daemon (d); |
266 | free (url); | 476 | return ret; |
267 | if (code != MHD_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE) | ||
268 | return 128; | ||
269 | return 0; | ||
270 | } | 477 | } |
271 | 478 | ||
272 | 479 | ||
@@ -285,6 +492,7 @@ main (int argc, char *const *argv) | |||
285 | daemon_port = 0; | 492 | daemon_port = 0; |
286 | else | 493 | else |
287 | daemon_port = oneone ? 1336 : 1331; | 494 | daemon_port = oneone ? 1336 : 1331; |
495 | |||
288 | errorCount += testLongUrlGet (VERY_LONG / 2); | 496 | errorCount += testLongUrlGet (VERY_LONG / 2); |
289 | errorCount += testLongUrlGet (VERY_LONG / 2 + 978); | 497 | errorCount += testLongUrlGet (VERY_LONG / 2 + 978); |
290 | errorCount += testLongHeaderGet (VERY_LONG / 2); | 498 | errorCount += testLongHeaderGet (VERY_LONG / 2); |