diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-11-28 18:53:02 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-12-19 18:13:44 +0300 |
commit | 38b46a2fd1cf24270e6deab2bb64c381938b95a9 (patch) | |
tree | f073f991f6fe0d5de829eb79a85d490d909079be | |
parent | 2a71dbd38f47cb067e61b681d7ac5dd39d26b754 (diff) | |
download | libmicrohttpd-38b46a2fd1cf24270e6deab2bb64c381938b95a9.tar.gz libmicrohttpd-38b46a2fd1cf24270e6deab2bb64c381938b95a9.zip |
test_parse_cookies: rewritten
Reused the same connection with the server.
Added more flexible checks.
-rw-r--r-- | src/testcurl/Makefile.am | 8 | ||||
-rw-r--r-- | src/testcurl/test_parse_cookies.c | 1445 |
2 files changed, 1062 insertions, 391 deletions
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am index cc685d3b..010ec2ef 100644 --- a/src/testcurl/Makefile.am +++ b/src/testcurl/Makefile.am | |||
@@ -145,7 +145,7 @@ check_PROGRAMS = \ | |||
145 | if ENABLE_COOKIE | 145 | if ENABLE_COOKIE |
146 | check_PROGRAMS += \ | 146 | check_PROGRAMS += \ |
147 | test_parse_cookies \ | 147 | test_parse_cookies \ |
148 | test_parse_cookies_invalid | 148 | test_parse_cookies_nonstrict |
149 | endif | 149 | endif |
150 | 150 | ||
151 | if HEAVY_TESTS | 151 | if HEAVY_TESTS |
@@ -468,10 +468,10 @@ test_process_headers_SOURCES = \ | |||
468 | test_process_headers.c mhd_has_in_name.h | 468 | test_process_headers.c mhd_has_in_name.h |
469 | 469 | ||
470 | test_parse_cookies_SOURCES = \ | 470 | test_parse_cookies_SOURCES = \ |
471 | test_parse_cookies.c mhd_has_in_name.h | 471 | test_parse_cookies.c mhd_has_in_name.h mhd_has_param.h |
472 | 472 | ||
473 | test_parse_cookies_invalid_SOURCES = \ | 473 | test_parse_cookies_nonstrict_SOURCES = \ |
474 | test_parse_cookies.c mhd_has_in_name.h | 474 | $(test_parse_cookies_SOURCES) |
475 | 475 | ||
476 | test_process_arguments_SOURCES = \ | 476 | test_process_arguments_SOURCES = \ |
477 | test_process_arguments.c mhd_has_in_name.h | 477 | test_process_arguments.c mhd_has_in_name.h |
diff --git a/src/testcurl/test_parse_cookies.c b/src/testcurl/test_parse_cookies.c index d02a2b76..987ddbf4 100644 --- a/src/testcurl/test_parse_cookies.c +++ b/src/testcurl/test_parse_cookies.c | |||
@@ -1,14 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of libmicrohttpd | 2 | This file is part of GNU libmicrohttpd |
3 | Copyright (C) 2007 Christian Grothoff | 3 | Copyright (C) 2007 Christian Grothoff |
4 | Copyright (C) 2014-2022 Evgeny Grin (Karlson2k) | 4 | Copyright (C) 2016-2022 Evgeny Grin (Karlson2k) |
5 | 5 | ||
6 | libmicrohttpd is free software; you can redistribute it and/or modify | 6 | GNU 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 |
8 | by the Free Software Foundation; either version 3, or (at your | 8 | by the Free Software Foundation; either version 2, or (at your |
9 | option) any later version. | 9 | option) any later version. |
10 | 10 | ||
11 | libmicrohttpd is distributed in the hope that it will be useful, but | 11 | GNU libmicrohttpd is distributed in the hope that it will be useful, but |
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | General Public License for more details. | 14 | General Public License for more details. |
@@ -22,522 +22,1193 @@ | |||
22 | /** | 22 | /** |
23 | * @file test_parse_cookies.c | 23 | * @file test_parse_cookies.c |
24 | * @brief Testcase for HTTP cookie parsing | 24 | * @brief Testcase for HTTP cookie parsing |
25 | * @author Christian Grothoff | ||
26 | * @author Karlson2k (Evgeny Grin) | 25 | * @author Karlson2k (Evgeny Grin) |
26 | * @author Christian Grothoff | ||
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> | ||
35 | #include <string.h> | 34 | #include <string.h> |
36 | #include <time.h> | 35 | #include <time.h> |
37 | #include "mhd_has_in_name.h" | ||
38 | 36 | ||
39 | #ifndef WINDOWS | 37 | #ifndef _WIN32 |
38 | #include <sys/socket.h> | ||
40 | #include <unistd.h> | 39 | #include <unistd.h> |
41 | #endif | 40 | #endif |
42 | 41 | ||
43 | static int use_invalid; | 42 | #include "mhd_has_param.h" |
43 | #include "mhd_has_in_name.h" | ||
44 | 44 | ||
45 | struct CBC | 45 | #ifndef MHD_STATICSTR_LEN_ |
46 | { | 46 | /** |
47 | char *buf; | 47 | * Determine length of static string / macro strings at compile time. |
48 | size_t pos; | 48 | */ |
49 | size_t size; | 49 | #define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1) |
50 | }; | 50 | #endif /* ! MHD_STATICSTR_LEN_ */ |
51 | 51 | ||
52 | static size_t | 52 | #ifndef CURL_VERSION_BITS |
53 | copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx) | 53 | #define CURL_VERSION_BITS(x,y,z) ((x) << 16 | (y) << 8 | (z)) |
54 | #endif /* ! CURL_VERSION_BITS */ | ||
55 | #ifndef CURL_AT_LEAST_VERSION | ||
56 | #define CURL_AT_LEAST_VERSION(x,y,z) \ | ||
57 | (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS (x, y, z)) | ||
58 | #endif /* ! CURL_AT_LEAST_VERSION */ | ||
59 | |||
60 | #ifndef _MHD_INSTRMACRO | ||
61 | /* Quoted macro parameter */ | ||
62 | #define _MHD_INSTRMACRO(a) #a | ||
63 | #endif /* ! _MHD_INSTRMACRO */ | ||
64 | #ifndef _MHD_STRMACRO | ||
65 | /* Quoted expanded macro parameter */ | ||
66 | #define _MHD_STRMACRO(a) _MHD_INSTRMACRO (a) | ||
67 | #endif /* ! _MHD_STRMACRO */ | ||
68 | |||
69 | #if defined(HAVE___FUNC__) | ||
70 | #define externalErrorExit(ignore) \ | ||
71 | _externalErrorExit_func (NULL, __func__, __LINE__) | ||
72 | #define externalErrorExitDesc(errDesc) \ | ||
73 | _externalErrorExit_func (errDesc, __func__, __LINE__) | ||
74 | #define libcurlErrorExit(ignore) \ | ||
75 | _libcurlErrorExit_func (NULL, __func__, __LINE__) | ||
76 | #define libcurlErrorExitDesc(errDesc) \ | ||
77 | _libcurlErrorExit_func (errDesc, __func__, __LINE__) | ||
78 | #define mhdErrorExit(ignore) \ | ||
79 | _mhdErrorExit_func (NULL, __func__, __LINE__) | ||
80 | #define mhdErrorExitDesc(errDesc) \ | ||
81 | _mhdErrorExit_func (errDesc, __func__, __LINE__) | ||
82 | #define checkCURLE_OK(libcurlcall) \ | ||
83 | _checkCURLE_OK_func ((libcurlcall), _MHD_STRMACRO (libcurlcall), \ | ||
84 | __func__, __LINE__) | ||
85 | #elif defined(HAVE___FUNCTION__) | ||
86 | #define externalErrorExit(ignore) \ | ||
87 | _externalErrorExit_func (NULL, __FUNCTION__, __LINE__) | ||
88 | #define externalErrorExitDesc(errDesc) \ | ||
89 | _externalErrorExit_func (errDesc, __FUNCTION__, __LINE__) | ||
90 | #define libcurlErrorExit(ignore) \ | ||
91 | _libcurlErrorExit_func (NULL, __FUNCTION__, __LINE__) | ||
92 | #define libcurlErrorExitDesc(errDesc) \ | ||
93 | _libcurlErrorExit_func (errDesc, __FUNCTION__, __LINE__) | ||
94 | #define mhdErrorExit(ignore) \ | ||
95 | _mhdErrorExit_func (NULL, __FUNCTION__, __LINE__) | ||
96 | #define mhdErrorExitDesc(errDesc) \ | ||
97 | _mhdErrorExit_func (errDesc, __FUNCTION__, __LINE__) | ||
98 | #define checkCURLE_OK(libcurlcall) \ | ||
99 | _checkCURLE_OK_func ((libcurlcall), _MHD_STRMACRO (libcurlcall), \ | ||
100 | __FUNCTION__, __LINE__) | ||
101 | #else | ||
102 | #define externalErrorExit(ignore) _externalErrorExit_func (NULL, NULL, __LINE__) | ||
103 | #define externalErrorExitDesc(errDesc) \ | ||
104 | _externalErrorExit_func (errDesc, NULL, __LINE__) | ||
105 | #define libcurlErrorExit(ignore) _libcurlErrorExit_func (NULL, NULL, __LINE__) | ||
106 | #define libcurlErrorExitDesc(errDesc) \ | ||
107 | _libcurlErrorExit_func (errDesc, NULL, __LINE__) | ||
108 | #define mhdErrorExit(ignore) _mhdErrorExit_func (NULL, NULL, __LINE__) | ||
109 | #define mhdErrorExitDesc(errDesc) _mhdErrorExit_func (errDesc, NULL, __LINE__) | ||
110 | #define checkCURLE_OK(libcurlcall) \ | ||
111 | _checkCURLE_OK_func ((libcurlcall), _MHD_STRMACRO (libcurlcall), NULL, \ | ||
112 | __LINE__) | ||
113 | #endif | ||
114 | |||
115 | |||
116 | _MHD_NORETURN static void | ||
117 | _externalErrorExit_func (const char *errDesc, const char *funcName, int lineNum) | ||
54 | { | 118 | { |
55 | struct CBC *cbc = ctx; | 119 | fflush (stdout); |
120 | if ((NULL != errDesc) && (0 != errDesc[0])) | ||
121 | fprintf (stderr, "%s", errDesc); | ||
122 | else | ||
123 | fprintf (stderr, "System or external library call failed"); | ||
124 | if ((NULL != funcName) && (0 != funcName[0])) | ||
125 | fprintf (stderr, " in %s", funcName); | ||
126 | if (0 < lineNum) | ||
127 | fprintf (stderr, " at line %d", lineNum); | ||
56 | 128 | ||
57 | if (cbc->pos + size * nmemb > cbc->size) | 129 | fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno, |
58 | return 0; /* overflow */ | 130 | strerror (errno)); |
59 | memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb); | 131 | #ifdef MHD_WINSOCK_SOCKETS |
60 | cbc->pos += size * nmemb; | 132 | fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ()); |
61 | return size * nmemb; | 133 | #endif /* MHD_WINSOCK_SOCKETS */ |
134 | fflush (stderr); | ||
135 | exit (99); | ||
62 | } | 136 | } |
63 | 137 | ||
64 | 138 | ||
65 | static enum MHD_Result | 139 | static char libcurl_errbuf[CURL_ERROR_SIZE] = ""; |
66 | ahc_echo (void *cls, | 140 | |
67 | struct MHD_Connection *connection, | 141 | _MHD_NORETURN static void |
68 | const char *url, | 142 | _libcurlErrorExit_func (const char *errDesc, const char *funcName, int lineNum) |
69 | const char *method, | ||
70 | const char *version, | ||
71 | const char *upload_data, size_t *upload_data_size, | ||
72 | void **req_cls) | ||
73 | { | 143 | { |
74 | static int ptr; | 144 | fflush (stdout); |
75 | const int *puse_invalid = cls; | 145 | if ((NULL != errDesc) && (0 != errDesc[0])) |
76 | struct MHD_Response *response; | 146 | fprintf (stderr, "%s", errDesc); |
77 | enum MHD_Result ret; | 147 | else |
78 | const char *hdr; | 148 | fprintf (stderr, "CURL library call failed"); |
79 | (void) version; (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler warning. */ | 149 | if ((NULL != funcName) && (0 != funcName[0])) |
150 | fprintf (stderr, " in %s", funcName); | ||
151 | if (0 < lineNum) | ||
152 | fprintf (stderr, " at line %d", lineNum); | ||
80 | 153 | ||
81 | if (0 != strcmp (MHD_HTTP_METHOD_GET, method)) | 154 | fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno, |
82 | return MHD_NO; /* unexpected method */ | 155 | strerror (errno)); |
83 | if (&ptr != *req_cls) | 156 | #ifdef MHD_WINSOCK_SOCKETS |
84 | { | 157 | fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ()); |
85 | *req_cls = &ptr; | 158 | #endif /* MHD_WINSOCK_SOCKETS */ |
86 | return MHD_YES; | 159 | if (0 != libcurl_errbuf[0]) |
87 | } | 160 | fprintf (stderr, "Last libcurl error description: %s\n", libcurl_errbuf); |
88 | *req_cls = NULL; | ||
89 | 161 | ||
90 | if (! *puse_invalid) | 162 | fflush (stderr); |
91 | { | 163 | exit (99); |
92 | hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name1"); | 164 | } |
93 | if ((hdr == NULL) || (0 != strcmp (hdr, "var1"))) | 165 | |
94 | { | 166 | |
95 | fprintf (stderr, "'name1' cookie decoded incorrectly.\n"); | 167 | _MHD_NORETURN static void |
96 | exit (11); | 168 | _mhdErrorExit_func (const char *errDesc, const char *funcName, int lineNum) |
97 | } | 169 | { |
98 | hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name2"); | 170 | fflush (stdout); |
99 | if ((hdr == NULL) || (0 != strcmp (hdr, "var2"))) | 171 | if ((NULL != errDesc) && (0 != errDesc[0])) |
100 | { | 172 | fprintf (stderr, "%s", errDesc); |
101 | fprintf (stderr, "'name2' cookie decoded incorrectly.\n"); | ||
102 | exit (11); | ||
103 | } | ||
104 | hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name3"); | ||
105 | if ((hdr == NULL) || (0 != strcmp (hdr, ""))) | ||
106 | { | ||
107 | fprintf (stderr, "'name3' cookie decoded incorrectly.\n"); | ||
108 | exit (11); | ||
109 | } | ||
110 | hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name4"); | ||
111 | if ((hdr == NULL) || (0 != strcmp (hdr, "var4 with spaces"))) | ||
112 | { | ||
113 | fprintf (stderr, "'name4' cookie decoded incorrectly.\n"); | ||
114 | exit (11); | ||
115 | } | ||
116 | hdr = MHD_lookup_connection_value (connection, MHD_COOKIE_KIND, "name5"); | ||
117 | if ((hdr == NULL) || (0 != strcmp (hdr, "var_with_=_char"))) | ||
118 | { | ||
119 | fprintf (stderr, "'name5' cookie decoded incorrectly.\n"); | ||
120 | exit (11); | ||
121 | } | ||
122 | if (5 != MHD_get_connection_values_n (connection, MHD_COOKIE_KIND, | ||
123 | NULL, NULL)) | ||
124 | { | ||
125 | fprintf (stderr, "The total number of cookie is not five.\n"); | ||
126 | exit (12); | ||
127 | } | ||
128 | } | ||
129 | else | 173 | else |
130 | { | 174 | fprintf (stderr, "MHD unexpected error"); |
131 | if (0 != MHD_get_connection_values_n (connection, MHD_COOKIE_KIND, | 175 | if ((NULL != funcName) && (0 != funcName[0])) |
132 | NULL, NULL)) | 176 | fprintf (stderr, " in %s", funcName); |
133 | { | 177 | if (0 < lineNum) |
134 | fprintf (stderr, "The total number of cookie is not zero.\n"); | 178 | fprintf (stderr, " at line %d", lineNum); |
135 | exit (12); | 179 | |
136 | } | 180 | fprintf (stderr, ".\nLast errno value: %d (%s)\n", (int) errno, |
137 | } | 181 | strerror (errno)); |
138 | response = MHD_create_response_from_buffer_copy (strlen (url), | 182 | #ifdef MHD_WINSOCK_SOCKETS |
139 | url); | 183 | fprintf (stderr, "WSAGetLastError() value: %d\n", (int) WSAGetLastError ()); |
140 | ret = MHD_queue_response (connection, MHD_HTTP_OK, response); | 184 | #endif /* MHD_WINSOCK_SOCKETS */ |
141 | MHD_destroy_response (response); | 185 | |
142 | if (ret == MHD_NO) | 186 | fflush (stderr); |
143 | abort (); | 187 | exit (8); |
144 | return ret; | ||
145 | } | 188 | } |
146 | 189 | ||
147 | 190 | ||
148 | /* Re-use the same port for all checks */ | 191 | /* Could be increased to facilitate debugging */ |
149 | static uint16_t port; | 192 | #define TIMEOUTS_VAL 5 |
150 | 193 | ||
151 | static unsigned int | 194 | #define EXPECTED_URI_BASE_PATH "/" |
152 | testExternalGet (int test_number) | 195 | |
196 | #define URL_SCHEME "http:/" "/" | ||
197 | |||
198 | #define URL_HOST "127.0.0.1" | ||
199 | |||
200 | #define URL_SCHEME_HOST URL_SCHEME URL_HOST | ||
201 | |||
202 | #define PAGE \ | ||
203 | "<html><head><title>libmicrohttpd test page</title></head>" \ | ||
204 | "<body>Success!</body></html>" | ||
205 | |||
206 | |||
207 | #ifndef MHD_STATICSTR_LEN_ | ||
208 | /** | ||
209 | * Determine length of static string / macro strings at compile time. | ||
210 | */ | ||
211 | #define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1) | ||
212 | #endif /* ! MHD_STATICSTR_LEN_ */ | ||
213 | |||
214 | |||
215 | struct strct_str_len | ||
153 | { | 216 | { |
154 | struct MHD_Daemon *d; | 217 | const char *str; |
155 | CURL *c; | 218 | const size_t len; |
156 | char buf[2048]; | 219 | }; |
157 | struct CBC cbc; | ||
158 | CURLM *multi; | ||
159 | CURLMcode mret; | ||
160 | fd_set rs; | ||
161 | fd_set ws; | ||
162 | fd_set es; | ||
163 | MHD_socket maxsock; | ||
164 | #ifdef MHD_WINSOCK_SOCKETS | ||
165 | int maxposixs; /* Max socket number unused on W32 */ | ||
166 | #else /* MHD_POSIX_SOCKETS */ | ||
167 | #define maxposixs maxsock | ||
168 | #endif /* MHD_POSIX_SOCKETS */ | ||
169 | int running; | ||
170 | struct CURLMsg *msg; | ||
171 | time_t start; | ||
172 | struct timeval tv; | ||
173 | 220 | ||
174 | multi = NULL; | 221 | #define STR_LEN_(str) {str, MHD_STATICSTR_LEN_(str)} |
175 | cbc.buf = buf; | 222 | #define STR_NULL_ {NULL, 0} |
176 | cbc.size = 2048; | 223 | |
177 | cbc.pos = 0; | 224 | struct strct_cookie |
178 | d = MHD_start_daemon (MHD_USE_ERROR_LOG, | 225 | { |
179 | port, NULL, NULL, &ahc_echo, &use_invalid, | 226 | struct strct_str_len name; |
180 | MHD_OPTION_END); | 227 | struct strct_str_len value; |
181 | if (d == NULL) | 228 | }; |
182 | return 256; | 229 | |
183 | if (0 == port) | 230 | #define COOKIE_(name,value) {STR_LEN_(name), STR_LEN_(value)} |
231 | #define COOKIE_NULL {STR_NULL_, STR_NULL_} | ||
232 | |||
233 | struct strct_test_data | ||
234 | { | ||
235 | unsigned int line_num; | ||
236 | const char *header_str; | ||
237 | unsigned int num_cookies_non_strict; | ||
238 | unsigned int num_cookies_strict; | ||
239 | struct strct_cookie cookies[5]; | ||
240 | }; | ||
241 | |||
242 | static const struct strct_test_data test_data[] = { | ||
184 | { | 243 | { |
185 | const union MHD_DaemonInfo *dinfo; | 244 | __LINE__, |
186 | dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT); | 245 | "name1=var1; name2=var2; name3=; " \ |
187 | if ((NULL == dinfo) || (0 == dinfo->port) ) | 246 | "name4=\"var4 with spaces\"; " \ |
247 | "name5=var_with_=_char", | ||
248 | 5, | ||
249 | 0, | ||
188 | { | 250 | { |
189 | MHD_stop_daemon (d); return 32; | 251 | COOKIE_ ("name1", "var1"), |
252 | COOKIE_ ("name2", "var2"), | ||
253 | COOKIE_ ("name3", ""), | ||
254 | COOKIE_ ("name4", "var4 with spaces"), | ||
255 | COOKIE_ ("name5", "var_with_=_char") | ||
190 | } | 256 | } |
191 | port = dinfo->port; | 257 | }, |
192 | } | ||
193 | c = curl_easy_init (); | ||
194 | curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1/hello_world"); | ||
195 | curl_easy_setopt (c, CURLOPT_PORT, (long) port); | ||
196 | curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer); | ||
197 | curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc); | ||
198 | curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L); | ||
199 | if (! use_invalid) | ||
200 | { | 258 | { |
201 | if (0 == test_number) | 259 | __LINE__, |
260 | "name1=var1;name2=var2;name3=;" \ | ||
261 | "name4=\"var4 with spaces\";" \ | ||
262 | "name5=var_with_=_char", | ||
263 | 5, | ||
264 | 0, | ||
202 | { | 265 | { |
203 | curl_easy_setopt (c, CURLOPT_COOKIE, | 266 | COOKIE_ ("name1", "var1"), |
204 | "name1=var1; name2=var2; name3=; " \ | 267 | COOKIE_ ("name2", "var2"), |
205 | "name4=\"var4 with spaces\"; " \ | 268 | COOKIE_ ("name3", ""), |
206 | "name5=var_with_=_char"); | 269 | COOKIE_ ("name4", "var4 with spaces"), |
270 | COOKIE_ ("name5", "var_with_=_char") | ||
207 | } | 271 | } |
208 | else if (1 == test_number) | 272 | }, |
273 | { | ||
274 | __LINE__, | ||
275 | "name1=var1; name2=var2; name3=; " \ | ||
276 | "name4=\"var4 with spaces\"; " \ | ||
277 | "name5=var_with_=_char\t \t", | ||
278 | 5, | ||
279 | 0, | ||
209 | { | 280 | { |
210 | curl_easy_setopt (c, CURLOPT_COOKIE, | 281 | COOKIE_ ("name1", "var1"), |
211 | "name1=var1;name2=var2;name3=;" \ | 282 | COOKIE_ ("name2", "var2"), |
212 | "name4=\"var4 with spaces\";" \ | 283 | COOKIE_ ("name3", ""), |
213 | "name5=var_with_=_char"); | 284 | COOKIE_ ("name4", "var4 with spaces"), |
285 | COOKIE_ ("name5", "var_with_=_char") | ||
214 | } | 286 | } |
215 | else if (2 == test_number) | 287 | }, |
288 | { | ||
289 | __LINE__, | ||
290 | "name1=var1;;name2=var2;;name3=;;" \ | ||
291 | "name4=\"var4 with spaces\";;" \ | ||
292 | "name5=var_with_=_char;\t \t", | ||
293 | 5, | ||
294 | 0, | ||
216 | { | 295 | { |
217 | curl_easy_setopt (c, CURLOPT_COOKIE, | 296 | COOKIE_ ("name1", "var1"), |
218 | "name1=var1; name2=var2; name3=; " \ | 297 | COOKIE_ ("name2", "var2"), |
219 | "name4=\"var4 with spaces\"; " \ | 298 | COOKIE_ ("name3", ""), |
220 | "name5=var_with_=_char\t \t"); | 299 | COOKIE_ ("name4", "var4 with spaces"), |
300 | COOKIE_ ("name5", "var_with_=_char") | ||
221 | } | 301 | } |
222 | else if (3 == test_number) | 302 | }, |
303 | { | ||
304 | __LINE__, | ||
305 | "name3=; name1=var1; name2=var2; " \ | ||
306 | "name5=var_with_=_char;" \ | ||
307 | "name4=\"var4 with spaces\"", | ||
308 | 5, | ||
309 | 0, | ||
223 | { | 310 | { |
224 | curl_easy_setopt (c, CURLOPT_COOKIE, | 311 | COOKIE_ ("name1", "var1"), |
225 | "name1=var1;;name2=var2;;name3=;;" \ | 312 | COOKIE_ ("name2", "var2"), |
226 | "name4=\"var4 with spaces\";;" \ | 313 | COOKIE_ ("name3", ""), |
227 | "name5=var_with_=_char;\t \t"); | 314 | COOKIE_ ("name4", "var4 with spaces"), |
315 | COOKIE_ ("name5", "var_with_=_char") | ||
228 | } | 316 | } |
229 | else if (4 == test_number) | 317 | }, |
318 | { | ||
319 | __LINE__, | ||
320 | "name2=var2; name1=var1; " \ | ||
321 | "name5=var_with_=_char; name3=; " \ | ||
322 | "name4=\"var4 with spaces\";", | ||
323 | 5, | ||
324 | 0, | ||
230 | { | 325 | { |
231 | curl_easy_setopt (c, CURLOPT_COOKIE, | 326 | COOKIE_ ("name1", "var1"), |
232 | "name1=var1 ;name2=var2 ;name3= ;" \ | 327 | COOKIE_ ("name2", "var2"), |
233 | "name4=\"var4 with spaces\" ;" \ | 328 | COOKIE_ ("name3", ""), |
234 | "name5=var_with_=_char ;"); | 329 | COOKIE_ ("name4", "var4 with spaces"), |
330 | COOKIE_ ("name5", "var_with_=_char") | ||
235 | } | 331 | } |
236 | else if (5 == test_number) | 332 | }, |
333 | { | ||
334 | __LINE__, | ||
335 | "name2=var2; name1=var1; " \ | ||
336 | "name5=var_with_=_char; " \ | ||
337 | "name4=\"var4 with spaces\"; name3=", | ||
338 | 5, | ||
339 | 0, | ||
237 | { | 340 | { |
238 | curl_easy_setopt (c, CURLOPT_COOKIE, | 341 | COOKIE_ ("name1", "var1"), |
239 | "name3=; name1=var1; name2=var2; " \ | 342 | COOKIE_ ("name2", "var2"), |
240 | "name5=var_with_=_char;" \ | 343 | COOKIE_ ("name3", ""), |
241 | "name4=\"var4 with spaces\""); | 344 | COOKIE_ ("name4", "var4 with spaces"), |
345 | COOKIE_ ("name5", "var_with_=_char") | ||
242 | } | 346 | } |
243 | else if (6 == test_number) | 347 | }, |
348 | { | ||
349 | __LINE__, | ||
350 | "name2=var2; name1=var1; " \ | ||
351 | "name4=\"var4 with spaces\"; " \ | ||
352 | "name5=var_with_=_char; name3=;", | ||
353 | 5, | ||
354 | 0, | ||
244 | { | 355 | { |
245 | curl_easy_setopt (c, CURLOPT_COOKIE, | 356 | COOKIE_ ("name1", "var1"), |
246 | "name2=var2; name1=var1; " \ | 357 | COOKIE_ ("name2", "var2"), |
247 | "name5=var_with_=_char; name3=; " \ | 358 | COOKIE_ ("name3", ""), |
248 | "name4=\"var4 with spaces\";"); | 359 | COOKIE_ ("name4", "var4 with spaces"), |
360 | COOKIE_ ("name5", "var_with_=_char") | ||
249 | } | 361 | } |
250 | else if (7 == test_number) | 362 | }, |
363 | { | ||
364 | __LINE__, | ||
365 | ";;;;;;;;name1=var1; name2=var2; name3=; " \ | ||
366 | "name4=\"var4 with spaces\"; " \ | ||
367 | "name5=var_with_=_char", | ||
368 | 5, | ||
369 | 0, | ||
251 | { | 370 | { |
252 | curl_easy_setopt (c, CURLOPT_COOKIE, | 371 | COOKIE_ ("name1", "var1"), |
253 | "name2=var2; name1=var1; " \ | 372 | COOKIE_ ("name2", "var2"), |
254 | "name5=var_with_=_char; " \ | 373 | COOKIE_ ("name3", ""), |
255 | "name4=\"var4 with spaces\"; name3="); | 374 | COOKIE_ ("name4", "var4 with spaces"), |
375 | COOKIE_ ("name5", "var_with_=_char") | ||
256 | } | 376 | } |
257 | else if (8 == test_number) | 377 | }, |
378 | { | ||
379 | __LINE__, | ||
380 | "name1=var1; name2=var2; name3=; " \ | ||
381 | "name4=\"var4 with spaces\"; ; ; ; ; " \ | ||
382 | "name5=var_with_=_char", | ||
383 | 5, | ||
384 | 0, | ||
258 | { | 385 | { |
259 | curl_easy_setopt (c, CURLOPT_COOKIE, | 386 | COOKIE_ ("name1", "var1"), |
260 | "name2=var2; name1=var1; " \ | 387 | COOKIE_ ("name2", "var2"), |
261 | "name4=\"var4 with spaces\"; " \ | 388 | COOKIE_ ("name3", ""), |
262 | "name5=var_with_=_char; name3=;"); | 389 | COOKIE_ ("name4", "var4 with spaces"), |
390 | COOKIE_ ("name5", "var_with_=_char") | ||
263 | } | 391 | } |
264 | else if (9 == test_number) | 392 | }, |
393 | { | ||
394 | __LINE__, | ||
395 | "name1=var1; name2=var2; name3=; " \ | ||
396 | "name4=\"var4 with spaces\"; " \ | ||
397 | "name5=var_with_=_char;;;;;;;;", | ||
398 | 5, | ||
399 | 0, | ||
265 | { | 400 | { |
266 | curl_easy_setopt (c, CURLOPT_COOKIE, | 401 | COOKIE_ ("name1", "var1"), |
267 | ";;;;;;;;name1=var1; name2=var2; name3=; " \ | 402 | COOKIE_ ("name2", "var2"), |
268 | "name4=\"var4 with spaces\"; " \ | 403 | COOKIE_ ("name3", ""), |
269 | "name5=var_with_=_char"); | 404 | COOKIE_ ("name4", "var4 with spaces"), |
405 | COOKIE_ ("name5", "var_with_=_char") | ||
270 | } | 406 | } |
271 | else if (10 == test_number) | 407 | }, |
408 | { | ||
409 | __LINE__, | ||
410 | "name1=var1; name2=var2; " \ | ||
411 | "name4=\"var4 with spaces\"" \ | ||
412 | "name5=var_with_=_char; ; ; ; ; name3=", | ||
413 | 5, | ||
414 | 0, | ||
272 | { | 415 | { |
273 | curl_easy_setopt (c, CURLOPT_COOKIE, | 416 | COOKIE_ ("name1", "var1"), |
274 | "name1=var1; name2=var2; name3=; " \ | 417 | COOKIE_ ("name2", "var2"), |
275 | "name4=\"var4 with spaces\"; ; ; ; ; " \ | 418 | COOKIE_ ("name3", ""), |
276 | "name5=var_with_=_char"); | 419 | COOKIE_ ("name4", "var4 with spaces"), |
420 | COOKIE_ ("name5", "var_with_=_char") | ||
277 | } | 421 | } |
278 | else if (11 == test_number) | 422 | }, |
423 | { | ||
424 | __LINE__, | ||
425 | "name5=var_with_=_char ;" \ | ||
426 | "name1=var1; name2=var2; name3=; " \ | ||
427 | "name4=\"var4 with spaces\" ", | ||
428 | 5, | ||
429 | 0, | ||
279 | { | 430 | { |
280 | curl_easy_setopt (c, CURLOPT_COOKIE, | 431 | COOKIE_ ("name1", "var1"), |
281 | "name1=var1; name2=var2; name3=; " \ | 432 | COOKIE_ ("name2", "var2"), |
282 | "name4=\"var4 with spaces\"; " \ | 433 | COOKIE_ ("name3", ""), |
283 | "name5=var_with_=_char;;;;;;;;"); | 434 | COOKIE_ ("name4", "var4 with spaces"), |
435 | COOKIE_ ("name5", "var_with_=_char") | ||
284 | } | 436 | } |
285 | else if (12 == test_number) | 437 | }, |
438 | { | ||
439 | __LINE__, | ||
440 | "name5=var_with_=_char; name4=\"var4 with spaces\";" \ | ||
441 | "name1=var1; name2=var2; name3=", | ||
442 | 5, | ||
443 | 0, | ||
286 | { | 444 | { |
287 | curl_easy_setopt (c, CURLOPT_COOKIE, | 445 | COOKIE_ ("name1", "var1"), |
288 | "name1=var1; name2=var2; " \ | 446 | COOKIE_ ("name2", "var2"), |
289 | "name4=\"var4 with spaces\"" \ | 447 | COOKIE_ ("name3", ""), |
290 | "name5=var_with_=_char; ; ; ; ; name3="); | 448 | COOKIE_ ("name4", "var4 with spaces"), |
449 | COOKIE_ ("name5", "var_with_=_char") | ||
291 | } | 450 | } |
292 | else if (13 == test_number) | 451 | }, |
452 | { | ||
453 | __LINE__, | ||
454 | "", | ||
455 | 0, | ||
456 | 0, | ||
293 | { | 457 | { |
294 | curl_easy_setopt (c, CURLOPT_COOKIE, | 458 | COOKIE_NULL, |
295 | "name5=var_with_=_char ;" \ | 459 | COOKIE_NULL, |
296 | "name1=var1; name2=var2; name3=; " \ | 460 | COOKIE_NULL, |
297 | "name4=\"var4 with spaces\" "); | 461 | COOKIE_NULL, |
462 | COOKIE_NULL | ||
298 | } | 463 | } |
299 | else if (14 == test_number) | 464 | }, |
465 | { | ||
466 | __LINE__, | ||
467 | " ", | ||
468 | 0, | ||
469 | 0, | ||
300 | { | 470 | { |
301 | curl_easy_setopt (c, CURLOPT_COOKIE, | 471 | COOKIE_NULL, |
302 | "name5=var_with_=_char; name4=\"var4 with spaces\";" \ | 472 | COOKIE_NULL, |
303 | "name1=var1; name2=var2; name3="); | 473 | COOKIE_NULL, |
474 | COOKIE_NULL, | ||
475 | COOKIE_NULL | ||
304 | } | 476 | } |
305 | } | 477 | }, |
306 | else | ||
307 | { | 478 | { |
308 | if (0 == test_number) | 479 | __LINE__, |
480 | "\t", | ||
481 | 0, | ||
482 | 0, | ||
309 | { | 483 | { |
310 | (void) 0; /* No cookie */ | 484 | COOKIE_NULL, |
485 | COOKIE_NULL, | ||
486 | COOKIE_NULL, | ||
487 | COOKIE_NULL, | ||
488 | COOKIE_NULL | ||
311 | } | 489 | } |
312 | else if (1 == test_number) | 490 | }, |
491 | { | ||
492 | __LINE__, | ||
493 | "var=,", | ||
494 | 0, | ||
495 | 0, | ||
313 | { | 496 | { |
314 | curl_easy_setopt (c, CURLOPT_COOKIE, | 497 | COOKIE_NULL, |
315 | ""); | 498 | COOKIE_NULL, |
499 | COOKIE_NULL, | ||
500 | COOKIE_NULL, | ||
501 | COOKIE_NULL | ||
316 | } | 502 | } |
317 | else if (2 == test_number) | 503 | }, |
504 | { | ||
505 | __LINE__, | ||
506 | "var=\"\\ \"", | ||
507 | 0, | ||
508 | 0, | ||
318 | { | 509 | { |
319 | curl_easy_setopt (c, CURLOPT_COOKIE, | 510 | COOKIE_NULL, |
320 | " "); | 511 | COOKIE_NULL, |
512 | COOKIE_NULL, | ||
513 | COOKIE_NULL, | ||
514 | COOKIE_NULL | ||
321 | } | 515 | } |
322 | else if (3 == test_number) | 516 | }, |
517 | { | ||
518 | __LINE__, | ||
519 | "var=value space", | ||
520 | 0, | ||
521 | 0, | ||
323 | { | 522 | { |
324 | curl_easy_setopt (c, CURLOPT_COOKIE, | 523 | COOKIE_NULL, |
325 | "\t"); | 524 | COOKIE_NULL, |
525 | COOKIE_NULL, | ||
526 | COOKIE_NULL, | ||
527 | COOKIE_NULL | ||
326 | } | 528 | } |
327 | else if (4 == test_number) | 529 | }, |
530 | { | ||
531 | __LINE__, | ||
532 | "var=value\ttab", | ||
533 | 0, | ||
534 | 0, | ||
328 | { | 535 | { |
329 | curl_easy_setopt (c, CURLOPT_COOKIE, | 536 | COOKIE_NULL, |
330 | "var=,"); | 537 | COOKIE_NULL, |
538 | COOKIE_NULL, | ||
539 | COOKIE_NULL, | ||
540 | COOKIE_NULL | ||
331 | } | 541 | } |
332 | else if (5 == test_number) | 542 | }, |
543 | { | ||
544 | __LINE__, | ||
545 | "=", | ||
546 | 0, | ||
547 | 0, | ||
333 | { | 548 | { |
334 | curl_easy_setopt (c, CURLOPT_COOKIE, | 549 | COOKIE_NULL, |
335 | "var=\"\\ \""); | 550 | COOKIE_NULL, |
551 | COOKIE_NULL, | ||
552 | COOKIE_NULL, | ||
553 | COOKIE_NULL | ||
336 | } | 554 | } |
337 | else if (6 == test_number) | 555 | }, |
556 | { | ||
557 | __LINE__, | ||
558 | "====", | ||
559 | 0, | ||
560 | 0, | ||
338 | { | 561 | { |
339 | curl_easy_setopt (c, CURLOPT_COOKIE, | 562 | COOKIE_NULL, |
340 | "var=value space"); | 563 | COOKIE_NULL, |
564 | COOKIE_NULL, | ||
565 | COOKIE_NULL, | ||
566 | COOKIE_NULL | ||
341 | } | 567 | } |
342 | else if (7 == test_number) | 568 | }, |
569 | { | ||
570 | __LINE__, | ||
571 | ";=", | ||
572 | 0, | ||
573 | 0, | ||
343 | { | 574 | { |
344 | curl_easy_setopt (c, CURLOPT_COOKIE, | 575 | COOKIE_NULL, |
345 | "var=value\ttab"); | 576 | COOKIE_NULL, |
577 | COOKIE_NULL, | ||
578 | COOKIE_NULL, | ||
579 | COOKIE_NULL | ||
346 | } | 580 | } |
347 | else if (8 == test_number) | 581 | }, |
582 | { | ||
583 | __LINE__, | ||
584 | "var", | ||
585 | 0, | ||
586 | 0, | ||
348 | { | 587 | { |
349 | curl_easy_setopt (c, CURLOPT_COOKIE, | 588 | COOKIE_NULL, |
350 | "="); | 589 | COOKIE_NULL, |
590 | COOKIE_NULL, | ||
591 | COOKIE_NULL, | ||
592 | COOKIE_NULL | ||
351 | } | 593 | } |
352 | else if (9 == test_number) | 594 | }, |
595 | { | ||
596 | __LINE__, | ||
597 | "=;", | ||
598 | 0, | ||
599 | 0, | ||
353 | { | 600 | { |
354 | curl_easy_setopt (c, CURLOPT_COOKIE, | 601 | COOKIE_NULL, |
355 | "===="); | 602 | COOKIE_NULL, |
603 | COOKIE_NULL, | ||
604 | COOKIE_NULL, | ||
605 | COOKIE_NULL | ||
356 | } | 606 | } |
357 | else if (10 == test_number) | 607 | }, |
608 | { | ||
609 | __LINE__, | ||
610 | "= ;", | ||
611 | 0, | ||
612 | 0, | ||
613 | { | ||
614 | COOKIE_NULL, | ||
615 | COOKIE_NULL, | ||
616 | COOKIE_NULL, | ||
617 | COOKIE_NULL, | ||
618 | COOKIE_NULL | ||
619 | } | ||
620 | }, | ||
621 | { | ||
622 | __LINE__, | ||
623 | ";= ;", | ||
624 | 0, | ||
625 | 0, | ||
358 | { | 626 | { |
359 | curl_easy_setopt (c, CURLOPT_COOKIE, | 627 | COOKIE_NULL, |
360 | ";="); | 628 | COOKIE_NULL, |
629 | COOKIE_NULL, | ||
630 | COOKIE_NULL, | ||
631 | COOKIE_NULL | ||
361 | } | 632 | } |
362 | else if (11 == test_number) | 633 | } |
634 | }; | ||
635 | |||
636 | /* Global parameters */ | ||
637 | static int verbose; | ||
638 | static int oneone; /**< If false use HTTP/1.0 for requests*/ | ||
639 | static int use_non_strict; | ||
640 | |||
641 | static void | ||
642 | test_global_init (void) | ||
643 | { | ||
644 | libcurl_errbuf[0] = 0; | ||
645 | |||
646 | if (0 != curl_global_init (CURL_GLOBAL_WIN32)) | ||
647 | externalErrorExit (); | ||
648 | } | ||
649 | |||
650 | |||
651 | static void | ||
652 | test_global_cleanup (void) | ||
653 | { | ||
654 | curl_global_cleanup (); | ||
655 | } | ||
656 | |||
657 | |||
658 | struct CBC | ||
659 | { | ||
660 | char *buf; | ||
661 | size_t pos; | ||
662 | size_t size; | ||
663 | }; | ||
664 | |||
665 | |||
666 | static size_t | ||
667 | copyBuffer (void *ptr, | ||
668 | size_t size, | ||
669 | size_t nmemb, | ||
670 | void *ctx) | ||
671 | { | ||
672 | struct CBC *cbc = ctx; | ||
673 | |||
674 | if (cbc->pos + size * nmemb > cbc->size) | ||
675 | return 0; /* overflow */ | ||
676 | memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb); | ||
677 | cbc->pos += size * nmemb; | ||
678 | return size * nmemb; | ||
679 | } | ||
680 | |||
681 | |||
682 | struct ahc_cls_type | ||
683 | { | ||
684 | const char *rq_method; | ||
685 | const char *rq_url; | ||
686 | const struct strct_test_data *check; | ||
687 | }; | ||
688 | |||
689 | |||
690 | static enum MHD_Result | ||
691 | ahcCheck (void *cls, | ||
692 | struct MHD_Connection *connection, | ||
693 | const char *url, | ||
694 | const char *method, | ||
695 | const char *version, | ||
696 | const char *upload_data, size_t *upload_data_size, | ||
697 | void **req_cls) | ||
698 | { | ||
699 | static int marker; | ||
700 | struct MHD_Response *response; | ||
701 | enum MHD_Result ret; | ||
702 | struct ahc_cls_type *const param = (struct ahc_cls_type *) cls; | ||
703 | const unsigned int expected_num_cookies = | ||
704 | use_non_strict ? param->check->num_cookies_non_strict : | ||
705 | param->check->num_cookies_strict; | ||
706 | unsigned int i; | ||
707 | int cookie_failed; | ||
708 | |||
709 | if (NULL == param) | ||
710 | mhdErrorExitDesc ("cls parameter is NULL"); | ||
711 | |||
712 | if (oneone) | ||
713 | { | ||
714 | if (0 != strcmp (version, MHD_HTTP_VERSION_1_1)) | ||
715 | mhdErrorExitDesc ("Unexpected HTTP version"); | ||
716 | } | ||
717 | else | ||
718 | { | ||
719 | if (0 != strcmp (version, MHD_HTTP_VERSION_1_0)) | ||
720 | mhdErrorExitDesc ("Unexpected HTTP version"); | ||
721 | } | ||
722 | |||
723 | if (0 != strcmp (url, param->rq_url)) | ||
724 | mhdErrorExitDesc ("Unexpected URI"); | ||
725 | |||
726 | if (NULL != upload_data) | ||
727 | mhdErrorExitDesc ("'upload_data' is not NULL"); | ||
728 | |||
729 | if (NULL == upload_data_size) | ||
730 | mhdErrorExitDesc ("'upload_data_size' pointer is NULL"); | ||
731 | |||
732 | if (0 != *upload_data_size) | ||
733 | mhdErrorExitDesc ("'*upload_data_size' value is not zero"); | ||
734 | |||
735 | if (0 != strcmp (param->rq_method, method)) | ||
736 | mhdErrorExitDesc ("Unexpected request method"); | ||
737 | |||
738 | cookie_failed = 0; | ||
739 | for (i = 0; i < expected_num_cookies; ++i) | ||
740 | { | ||
741 | const char *cookie_val; | ||
742 | size_t cookie_val_len; | ||
743 | const struct strct_cookie *const cookie_data = param->check->cookies + i; | ||
744 | if (NULL == cookie_data->name.str) | ||
745 | externalErrorExitDesc ("Broken test data"); | ||
746 | if (NULL == cookie_data->value.str) | ||
747 | externalErrorExitDesc ("Broken test data"); | ||
748 | |||
749 | cookie_val = | ||
750 | MHD_lookup_connection_value (connection, | ||
751 | MHD_COOKIE_KIND, | ||
752 | cookie_data->name.str); | ||
753 | if (cookie_val == NULL) | ||
363 | { | 754 | { |
364 | curl_easy_setopt (c, CURLOPT_COOKIE, | 755 | fprintf (stderr, "'%s' cookie not found.\n", |
365 | "var"); | 756 | cookie_data->name.str); |
757 | cookie_failed = 1; | ||
366 | } | 758 | } |
367 | else if (12 == test_number) | 759 | else if (0 != strcmp (cookie_val, |
760 | cookie_data->value.str)) | ||
368 | { | 761 | { |
369 | curl_easy_setopt (c, CURLOPT_COOKIE, | 762 | fprintf (stderr, "'%s' cookie decoded incorrectly.\n" |
370 | "=;"); | 763 | "Expected: %s\nGot: %s\n", |
764 | cookie_data->name.str, | ||
765 | cookie_data->value.str, | ||
766 | cookie_val); | ||
767 | cookie_failed = 1; | ||
371 | } | 768 | } |
372 | else if (13 == test_number) | 769 | else if (MHD_YES != |
770 | MHD_lookup_connection_value_n (connection, | ||
771 | MHD_COOKIE_KIND, | ||
772 | cookie_data->name.str, | ||
773 | cookie_data->name.len, | ||
774 | &cookie_val, &cookie_val_len)) | ||
373 | { | 775 | { |
374 | curl_easy_setopt (c, CURLOPT_COOKIE, | 776 | fprintf (stderr, "'%s' (length %lu) cookie not found.\n", |
375 | "= ;"); | 777 | cookie_data->name.str, |
778 | (unsigned long) cookie_data->name.len); | ||
779 | cookie_failed = 1; | ||
376 | } | 780 | } |
377 | else if (14 == test_number) | 781 | else |
378 | { | 782 | { |
379 | curl_easy_setopt (c, CURLOPT_COOKIE, | 783 | if (cookie_data->value.len != cookie_val_len) |
380 | ";= ;"); | 784 | { |
785 | fprintf (stderr, "'%s' (length %lu) cookie has wrong value length.\n" | ||
786 | "Expected: %lu\nGot: %lu\n", | ||
787 | cookie_data->name.str, | ||
788 | (unsigned long) cookie_data->name.len, | ||
789 | (unsigned long) cookie_data->value.len, | ||
790 | (unsigned long) cookie_val_len); | ||
791 | cookie_failed = 1; | ||
792 | } | ||
793 | else if (0 != memcmp (cookie_val, cookie_data->value.str, cookie_val_len)) | ||
794 | { | ||
795 | fprintf (stderr, "'%s' (length %lu) cookie has wrong value.\n" | ||
796 | "Expected: %.*s\nGot: %.*s\n", | ||
797 | cookie_data->name.str, | ||
798 | (unsigned long) cookie_data->name.len, | ||
799 | (int) cookie_data->value.len, cookie_data->value.str, | ||
800 | (int) cookie_val_len, cookie_val); | ||
801 | cookie_failed = 1; | ||
802 | } | ||
381 | } | 803 | } |
382 | } | 804 | } |
805 | if (((int) expected_num_cookies) != | ||
806 | MHD_get_connection_values_n (connection, MHD_COOKIE_KIND, NULL, NULL)) | ||
807 | { | ||
808 | fprintf (stderr, "Wrong total number of cookies.\n" | ||
809 | "Expected: %u\nGot: %d\n", | ||
810 | expected_num_cookies, | ||
811 | MHD_get_connection_values_n (connection, MHD_COOKIE_KIND, NULL, | ||
812 | NULL)); | ||
813 | cookie_failed = 1; | ||
814 | } | ||
815 | if (cookie_failed) | ||
816 | return MHD_NO; /* Break connection */ | ||
817 | |||
818 | if (&marker != *req_cls) | ||
819 | { | ||
820 | *req_cls = ▮ | ||
821 | return MHD_YES; | ||
822 | } | ||
823 | *req_cls = NULL; | ||
824 | |||
825 | response = | ||
826 | MHD_create_response_from_buffer_static (MHD_STATICSTR_LEN_ (PAGE), | ||
827 | PAGE); | ||
828 | if (NULL == response) | ||
829 | mhdErrorExitDesc ("Failed to create response"); | ||
830 | |||
831 | ret = MHD_queue_response (connection, | ||
832 | MHD_HTTP_OK, | ||
833 | response); | ||
834 | MHD_destroy_response (response); | ||
835 | if (MHD_YES != ret) | ||
836 | mhdErrorExitDesc ("Failed to queue response"); | ||
383 | 837 | ||
384 | curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); | 838 | return ret; |
385 | curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L); | 839 | } |
386 | curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L); | 840 | |
387 | /* NOTE: use of CONNECTTIMEOUT without also | 841 | |
388 | setting NOSIGNAL results in really weird | 842 | static int |
389 | crashes on my system! */ | 843 | libcurl_debug_cb (CURL *handle, |
390 | curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L); | 844 | curl_infotype type, |
845 | char *data, | ||
846 | size_t size, | ||
847 | void *userptr) | ||
848 | { | ||
849 | static const char excess_mark[] = "Excess found"; | ||
850 | static const size_t excess_mark_len = MHD_STATICSTR_LEN_ (excess_mark); | ||
391 | 851 | ||
852 | (void) handle; | ||
853 | (void) userptr; | ||
392 | 854 | ||
393 | multi = curl_multi_init (); | 855 | #ifdef _DEBUG |
394 | if (multi == NULL) | 856 | switch (type) |
395 | { | 857 | { |
396 | curl_easy_cleanup (c); | 858 | case CURLINFO_TEXT: |
397 | MHD_stop_daemon (d); | 859 | fprintf (stderr, "* %.*s", (int) size, data); |
398 | return 512; | 860 | break; |
861 | case CURLINFO_HEADER_IN: | ||
862 | fprintf (stderr, "< %.*s", (int) size, data); | ||
863 | break; | ||
864 | case CURLINFO_HEADER_OUT: | ||
865 | fprintf (stderr, "> %.*s", (int) size, data); | ||
866 | break; | ||
867 | case CURLINFO_DATA_IN: | ||
868 | #if 0 | ||
869 | fprintf (stderr, "<| %.*s\n", (int) size, data); | ||
870 | #endif | ||
871 | break; | ||
872 | case CURLINFO_DATA_OUT: | ||
873 | case CURLINFO_SSL_DATA_IN: | ||
874 | case CURLINFO_SSL_DATA_OUT: | ||
875 | case CURLINFO_END: | ||
876 | default: | ||
877 | break; | ||
878 | } | ||
879 | #endif /* _DEBUG */ | ||
880 | if (CURLINFO_TEXT == type) | ||
881 | { | ||
882 | if ((size >= excess_mark_len) && | ||
883 | (0 == memcmp (data, excess_mark, excess_mark_len))) | ||
884 | mhdErrorExitDesc ("Extra data has been detected in MHD reply"); | ||
399 | } | 885 | } |
400 | mret = curl_multi_add_handle (multi, c); | 886 | return 0; |
401 | if (mret != CURLM_OK) | 887 | } |
888 | |||
889 | |||
890 | static CURL * | ||
891 | setupCURL (void *cbc, uint16_t port) | ||
892 | { | ||
893 | CURL *c; | ||
894 | |||
895 | c = curl_easy_init (); | ||
896 | if (NULL == c) | ||
897 | libcurlErrorExitDesc ("curl_easy_init() failed"); | ||
898 | |||
899 | if ((CURLE_OK != curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L)) || | ||
900 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, | ||
901 | ©Buffer)) || | ||
902 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_WRITEDATA, cbc)) || | ||
903 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, | ||
904 | ((long) TIMEOUTS_VAL))) || | ||
905 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_HTTP_VERSION, | ||
906 | (oneone) ? | ||
907 | CURL_HTTP_VERSION_1_1 : | ||
908 | CURL_HTTP_VERSION_1_0)) || | ||
909 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_TIMEOUT, | ||
910 | ((long) TIMEOUTS_VAL))) || | ||
911 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_ERRORBUFFER, | ||
912 | libcurl_errbuf)) || | ||
913 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_FAILONERROR, 0L)) || | ||
914 | #ifdef _DEBUG | ||
915 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_VERBOSE, 1L)) || | ||
916 | #endif /* _DEBUG */ | ||
917 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_DEBUGFUNCTION, | ||
918 | &libcurl_debug_cb)) || | ||
919 | #if CURL_AT_LEAST_VERSION (7, 19, 4) | ||
920 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP)) || | ||
921 | #endif /* CURL_AT_LEAST_VERSION (7, 19, 4) */ | ||
922 | #if CURL_AT_LEAST_VERSION (7, 45, 0) | ||
923 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_DEFAULT_PROTOCOL, "http")) || | ||
924 | #endif /* CURL_AT_LEAST_VERSION (7, 45, 0) */ | ||
925 | (CURLE_OK != curl_easy_setopt (c, CURLOPT_PORT, ((long) port)))) | ||
926 | libcurlErrorExitDesc ("curl_easy_setopt() failed"); | ||
927 | |||
928 | if (CURLE_OK != | ||
929 | curl_easy_setopt (c, CURLOPT_URL, | ||
930 | URL_SCHEME_HOST EXPECTED_URI_BASE_PATH)) | ||
931 | libcurlErrorExitDesc ("Cannot set request URL"); | ||
932 | |||
933 | return c; | ||
934 | } | ||
935 | |||
936 | |||
937 | static CURLcode | ||
938 | performQueryExternal (struct MHD_Daemon *d, CURL *c, CURLM **multi_reuse) | ||
939 | { | ||
940 | CURLM *multi; | ||
941 | time_t start; | ||
942 | struct timeval tv; | ||
943 | CURLcode ret; | ||
944 | |||
945 | ret = CURLE_FAILED_INIT; /* will be replaced with real result */ | ||
946 | if (NULL != *multi_reuse) | ||
947 | multi = *multi_reuse; | ||
948 | else | ||
402 | { | 949 | { |
403 | curl_multi_cleanup (multi); | 950 | multi = curl_multi_init (); |
404 | curl_easy_cleanup (c); | 951 | if (multi == NULL) |
405 | MHD_stop_daemon (d); | 952 | libcurlErrorExitDesc ("curl_multi_init() failed"); |
406 | return 1024; | 953 | *multi_reuse = multi; |
407 | } | 954 | } |
955 | if (CURLM_OK != curl_multi_add_handle (multi, c)) | ||
956 | libcurlErrorExitDesc ("curl_multi_add_handle() failed"); | ||
957 | |||
408 | start = time (NULL); | 958 | start = time (NULL); |
409 | while ((time (NULL) - start < 5) && (multi != NULL)) | 959 | while (time (NULL) - start <= TIMEOUTS_VAL) |
410 | { | 960 | { |
411 | maxsock = MHD_INVALID_SOCKET; | 961 | fd_set rs; |
412 | maxposixs = -1; | 962 | fd_set ws; |
963 | fd_set es; | ||
964 | MHD_socket maxMhdSk; | ||
965 | int maxCurlSk; | ||
966 | int running; | ||
967 | |||
968 | maxMhdSk = MHD_INVALID_SOCKET; | ||
969 | maxCurlSk = -1; | ||
413 | FD_ZERO (&rs); | 970 | FD_ZERO (&rs); |
414 | FD_ZERO (&ws); | 971 | FD_ZERO (&ws); |
415 | FD_ZERO (&es); | 972 | FD_ZERO (&es); |
416 | curl_multi_perform (multi, &running); | 973 | if (NULL != multi) |
417 | mret = curl_multi_fdset (multi, &rs, &ws, &es, &maxposixs); | ||
418 | if (mret != CURLM_OK) | ||
419 | { | 974 | { |
420 | curl_multi_remove_handle (multi, c); | 975 | curl_multi_perform (multi, &running); |
421 | curl_multi_cleanup (multi); | 976 | if (0 == running) |
422 | curl_easy_cleanup (c); | 977 | { |
423 | MHD_stop_daemon (d); | 978 | struct CURLMsg *msg; |
424 | return 2048; | 979 | int msgLeft; |
980 | int totalMsgs = 0; | ||
981 | do | ||
982 | { | ||
983 | msg = curl_multi_info_read (multi, &msgLeft); | ||
984 | if (NULL == msg) | ||
985 | libcurlErrorExitDesc ("curl_multi_info_read() failed"); | ||
986 | totalMsgs++; | ||
987 | if (CURLMSG_DONE == msg->msg) | ||
988 | ret = msg->data.result; | ||
989 | } while (msgLeft > 0); | ||
990 | if (1 != totalMsgs) | ||
991 | { | ||
992 | fprintf (stderr, | ||
993 | "curl_multi_info_read returned wrong " | ||
994 | "number of results (%d).\n", | ||
995 | totalMsgs); | ||
996 | externalErrorExit (); | ||
997 | } | ||
998 | curl_multi_remove_handle (multi, c); | ||
999 | multi = NULL; | ||
1000 | } | ||
1001 | else | ||
1002 | { | ||
1003 | if (CURLM_OK != curl_multi_fdset (multi, &rs, &ws, &es, &maxCurlSk)) | ||
1004 | libcurlErrorExitDesc ("curl_multi_fdset() failed"); | ||
1005 | } | ||
425 | } | 1006 | } |
426 | if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxsock)) | 1007 | if (NULL == multi) |
427 | { | 1008 | { /* libcurl has finished, check whether MHD still needs to perform cleanup */ |
428 | curl_multi_remove_handle (multi, c); | 1009 | if (0 != MHD_get_timeout64s (d)) |
429 | curl_multi_cleanup (multi); | 1010 | break; /* MHD finished as well */ |
430 | curl_easy_cleanup (c); | ||
431 | MHD_stop_daemon (d); | ||
432 | return 4096; | ||
433 | } | 1011 | } |
1012 | if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &maxMhdSk)) | ||
1013 | mhdErrorExitDesc ("MHD_get_fdset() failed"); | ||
434 | tv.tv_sec = 0; | 1014 | tv.tv_sec = 0; |
435 | tv.tv_usec = 1000; | 1015 | tv.tv_usec = 200000; |
436 | if (-1 == select (maxposixs + 1, &rs, &ws, &es, &tv)) | 1016 | if (0 == MHD_get_timeout64s (d)) |
1017 | tv.tv_usec = 0; | ||
1018 | else | ||
1019 | { | ||
1020 | long curl_to = -1; | ||
1021 | curl_multi_timeout (multi, &curl_to); | ||
1022 | if (0 == curl_to) | ||
1023 | tv.tv_usec = 0; | ||
1024 | } | ||
1025 | #ifdef MHD_POSIX_SOCKETS | ||
1026 | if (maxMhdSk > maxCurlSk) | ||
1027 | maxCurlSk = maxMhdSk; | ||
1028 | #endif /* MHD_POSIX_SOCKETS */ | ||
1029 | if (-1 == select (maxCurlSk + 1, &rs, &ws, &es, &tv)) | ||
437 | { | 1030 | { |
438 | #ifdef MHD_POSIX_SOCKETS | 1031 | #ifdef MHD_POSIX_SOCKETS |
439 | if (EINTR != errno) | 1032 | if (EINTR != errno) |
440 | { | 1033 | externalErrorExitDesc ("Unexpected select() error"); |
441 | fprintf (stderr, "Unexpected select() error: %d. Line: %d\n", | ||
442 | (int) errno, __LINE__); | ||
443 | fflush (stderr); | ||
444 | exit (99); | ||
445 | } | ||
446 | #else | 1034 | #else |
447 | if ((WSAEINVAL != WSAGetLastError ()) || | 1035 | if ((WSAEINVAL != WSAGetLastError ()) || |
448 | (0 != rs.fd_count) || (0 != ws.fd_count) || (0 != es.fd_count) ) | 1036 | (0 != rs.fd_count) || (0 != ws.fd_count) || (0 != es.fd_count) ) |
449 | { | 1037 | externalErrorExitDesc ("Unexpected select() error"); |
450 | fprintf (stderr, "Unexpected select() error: %d. Line: %d\n", | 1038 | Sleep ((unsigned long) tv.tv_usec / 1000); |
451 | (int) WSAGetLastError (), __LINE__); | ||
452 | fflush (stderr); | ||
453 | exit (99); | ||
454 | } | ||
455 | Sleep (1); | ||
456 | #endif | 1039 | #endif |
457 | } | 1040 | } |
458 | curl_multi_perform (multi, &running); | 1041 | if (MHD_YES != MHD_run_from_select (d, &rs, &ws, &es)) |
459 | if (0 == running) | 1042 | mhdErrorExitDesc ("MHD_run_from_select() failed"); |
460 | { | 1043 | } |
461 | int pending; | 1044 | |
462 | int curl_fine = 0; | 1045 | return ret; |
463 | while (NULL != (msg = curl_multi_info_read (multi, &pending))) | 1046 | } |
464 | { | 1047 | |
465 | if (msg->msg == CURLMSG_DONE) | 1048 | |
466 | { | 1049 | /** |
467 | if (msg->data.result == CURLE_OK) | 1050 | * Check request result |
468 | curl_fine = 1; | 1051 | * @param curl_code the CURL easy return code |
469 | else | 1052 | * @param pcbc the pointer struct CBC |
470 | { | 1053 | * @return non-zero if success, zero if failed |
471 | fprintf (stderr, | 1054 | */ |
472 | "%s failed at %s:%d: `%s'\n", | 1055 | static unsigned int |
473 | "curl_multi_perform", | 1056 | check_result (CURLcode curl_code, CURL *c, long expected_code, |
474 | __FILE__, | 1057 | struct CBC *pcbc) |
475 | __LINE__, curl_easy_strerror (msg->data.result)); | 1058 | { |
476 | abort (); | 1059 | long code; |
477 | } | 1060 | unsigned int ret; |
478 | } | 1061 | |
479 | } | 1062 | if (CURLE_OK != curl_code) |
480 | if (! curl_fine) | 1063 | { |
481 | { | 1064 | fflush (stdout); |
482 | fprintf (stderr, "libcurl haven't returned OK code\n"); | 1065 | if (0 != libcurl_errbuf[0]) |
483 | abort (); | 1066 | fprintf (stderr, "Request failed. " |
484 | } | 1067 | "libcurl error: '%s'.\n" |
485 | curl_multi_remove_handle (multi, c); | 1068 | "libcurl error description: '%s'.\n", |
486 | curl_multi_cleanup (multi); | 1069 | curl_easy_strerror (curl_code), |
487 | curl_easy_cleanup (c); | 1070 | libcurl_errbuf); |
488 | c = NULL; | 1071 | else |
489 | multi = NULL; | 1072 | fprintf (stderr, "Request failed. " |
490 | } | 1073 | "libcurl error: '%s'.\n", |
491 | MHD_run (d); | 1074 | curl_easy_strerror (curl_code)); |
1075 | fflush (stderr); | ||
1076 | return 0; | ||
492 | } | 1077 | } |
493 | if (multi != NULL) | 1078 | |
1079 | if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code)) | ||
1080 | libcurlErrorExit (); | ||
1081 | |||
1082 | ret = 1; | ||
1083 | if (expected_code != code) | ||
494 | { | 1084 | { |
495 | curl_multi_remove_handle (multi, c); | 1085 | fprintf (stderr, "The response has wrong HTTP code: %ld\tExpected: %ld.\n", |
496 | curl_easy_cleanup (c); | 1086 | code, expected_code); |
497 | curl_multi_cleanup (multi); | 1087 | ret = 0; |
498 | } | 1088 | } |
499 | MHD_stop_daemon (d); | 1089 | else if (verbose) |
500 | if (cbc.pos != strlen ("/hello_world")) | 1090 | printf ("The response has expected HTTP code: %ld\n", expected_code); |
501 | return 8192; | 1091 | |
502 | if (0 != strncmp ("/hello_world", cbc.buf, strlen ("/hello_world"))) | 1092 | if (pcbc->pos != MHD_STATICSTR_LEN_ (PAGE)) |
503 | return 16384; | 1093 | { |
504 | return 0; | 1094 | fprintf (stderr, "Got %u bytes ('%.*s'), expected %u bytes. ", |
1095 | (unsigned) pcbc->pos, (int) pcbc->pos, pcbc->buf, | ||
1096 | (unsigned) MHD_STATICSTR_LEN_ (PAGE)); | ||
1097 | mhdErrorExitDesc ("Wrong returned data length"); | ||
1098 | } | ||
1099 | if (0 != memcmp (PAGE, pcbc->buf, pcbc->pos)) | ||
1100 | { | ||
1101 | fprintf (stderr, "Got invalid response '%.*s'. ", | ||
1102 | (int) pcbc->pos, pcbc->buf); | ||
1103 | mhdErrorExitDesc ("Wrong returned data"); | ||
1104 | } | ||
1105 | fflush (stderr); | ||
1106 | fflush (stdout); | ||
1107 | |||
1108 | return ret; | ||
505 | } | 1109 | } |
506 | 1110 | ||
507 | 1111 | ||
508 | int | 1112 | static unsigned int |
509 | main (int argc, char *const *argv) | 1113 | testExternalPolling (void) |
510 | { | 1114 | { |
511 | unsigned int errorCount = 0; | 1115 | struct MHD_Daemon *d; |
512 | (void) argc; /* Unused. Silent compiler warning. */ | 1116 | uint16_t port; |
1117 | struct CBC cbc; | ||
1118 | struct ahc_cls_type ahc_param; | ||
1119 | char buf[2048]; | ||
1120 | CURL *c; | ||
1121 | CURLM *multi_reuse; | ||
1122 | size_t i; | ||
1123 | int failed = 0; | ||
513 | 1124 | ||
514 | if ((NULL == argv) || (0 == argv[0])) | ||
515 | return 99; | ||
516 | use_invalid = has_in_name (argv[0], "_invalid"); | ||
517 | if (0 != curl_global_init (CURL_GLOBAL_WIN32)) | ||
518 | return 2; | ||
519 | if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) | 1125 | if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT)) |
520 | port = 0; | 1126 | port = 0; |
521 | else | 1127 | else |
1128 | port = 1340 + oneone ? 0 : 1 + use_non_strict ? 0 : 2; | ||
1129 | |||
1130 | d = MHD_start_daemon (MHD_USE_ERROR_LOG, | ||
1131 | port, NULL, NULL, | ||
1132 | &ahcCheck, &ahc_param, | ||
1133 | MHD_OPTION_STRICT_FOR_CLIENT, | ||
1134 | (int) (use_non_strict ? 0 : 1), | ||
1135 | MHD_OPTION_END); | ||
1136 | if (d == NULL) | ||
1137 | return 1; | ||
1138 | if (0 == port) | ||
522 | { | 1139 | { |
523 | port = 1340; | 1140 | const union MHD_DaemonInfo *dinfo; |
524 | if (use_invalid) | 1141 | |
525 | port += 5; | 1142 | dinfo = MHD_get_daemon_info (d, |
1143 | MHD_DAEMON_INFO_BIND_PORT); | ||
1144 | if ( (NULL == dinfo) || | ||
1145 | (0 == dinfo->port) ) | ||
1146 | mhdErrorExitDesc ("MHD_get_daemon_info() failed"); | ||
1147 | port = dinfo->port; | ||
526 | } | 1148 | } |
527 | errorCount += testExternalGet (0); | 1149 | |
528 | errorCount += testExternalGet (1); | 1150 | ahc_param.rq_method = MHD_HTTP_METHOD_GET; |
529 | errorCount += testExternalGet (2); | 1151 | ahc_param.rq_url = EXPECTED_URI_BASE_PATH; |
530 | errorCount += testExternalGet (3); | 1152 | cbc.buf = buf; |
531 | errorCount += testExternalGet (4); | 1153 | cbc.size = sizeof (buf); |
532 | errorCount += testExternalGet (5); | 1154 | memset (cbc.buf, 0, cbc.size); |
533 | errorCount += testExternalGet (6); | 1155 | c = setupCURL (&cbc, port); |
534 | errorCount += testExternalGet (7); | 1156 | multi_reuse = NULL; |
535 | errorCount += testExternalGet (8); | 1157 | for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i) |
536 | errorCount += testExternalGet (9); | 1158 | { |
537 | errorCount += testExternalGet (10); | 1159 | cbc.pos = 0; |
538 | errorCount += testExternalGet (11); | 1160 | ahc_param.check = test_data + i; |
1161 | if (CURLE_OK != | ||
1162 | curl_easy_setopt (c, CURLOPT_COOKIE, | ||
1163 | ahc_param.check->header_str)) | ||
1164 | libcurlErrorExitDesc ("Cannot set request cookies"); | ||
1165 | |||
1166 | if (check_result (performQueryExternal (d, c, &multi_reuse), c, | ||
1167 | MHD_HTTP_OK, &cbc)) | ||
1168 | { | ||
1169 | if (verbose) | ||
1170 | printf ("Got expected response for the check at line %u.\n", | ||
1171 | test_data[i].line_num); | ||
1172 | fflush (stdout); | ||
1173 | } | ||
1174 | else | ||
1175 | { | ||
1176 | fprintf (stderr, "FAILED request for the check at line %u.\n", | ||
1177 | test_data[i].line_num); | ||
1178 | fflush (stderr); | ||
1179 | failed = 1; | ||
1180 | } | ||
1181 | } | ||
1182 | |||
1183 | curl_easy_cleanup (c); | ||
1184 | if (NULL != multi_reuse) | ||
1185 | curl_multi_cleanup (multi_reuse); | ||
1186 | |||
1187 | MHD_stop_daemon (d); | ||
1188 | return failed ? 1 : 0; | ||
1189 | } | ||
1190 | |||
1191 | |||
1192 | int | ||
1193 | main (int argc, char *const *argv) | ||
1194 | { | ||
1195 | unsigned int errorCount = 0; | ||
1196 | |||
1197 | /* Test type and test parameters */ | ||
1198 | verbose = ! (has_param (argc, argv, "-q") || | ||
1199 | has_param (argc, argv, "--quiet") || | ||
1200 | has_param (argc, argv, "-s") || | ||
1201 | has_param (argc, argv, "--silent")); | ||
1202 | oneone = ! has_in_name (argv[0], "10"); | ||
1203 | use_non_strict = has_in_name (argv[0], "_nonstrict"); | ||
1204 | |||
1205 | test_global_init (); | ||
1206 | |||
1207 | errorCount += testExternalPolling (); | ||
539 | if (errorCount != 0) | 1208 | if (errorCount != 0) |
540 | fprintf (stderr, "Error (code: %u)\n", errorCount); | 1209 | fprintf (stderr, "Error (code: %u)\n", errorCount); |
541 | curl_global_cleanup (); | 1210 | |
1211 | test_global_cleanup (); | ||
1212 | |||
542 | return (0 == errorCount) ? 0 : 1; /* 0 == pass */ | 1213 | return (0 == errorCount) ? 0 : 1; /* 0 == pass */ |
543 | } | 1214 | } |