aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/daemontest_long_header.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/daemontest_long_header.c')
-rw-r--r--src/daemon/daemontest_long_header.c287
1 files changed, 287 insertions, 0 deletions
diff --git a/src/daemon/daemontest_long_header.c b/src/daemon/daemontest_long_header.c
new file mode 100644
index 00000000..48635704
--- /dev/null
+++ b/src/daemon/daemontest_long_header.c
@@ -0,0 +1,287 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 Christian Grothoff
4
5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file daemontest_long_header.c
23 * @brief Testcase for libmicrohttpd handling of very long headers
24 * @author Christian Grothoff
25 */
26
27#include "config.h"
28#include <curl/curl.h>
29#include <microhttpd.h>
30#include <stdlib.h>
31#include <unistd.h>
32#include <string.h>
33#include <time.h>
34
35/**
36 * We will set the memory available per connection to
37 * half of this value, so the actual value does not have
38 * to be big at all...
39 */
40#define VERY_LONG (1024*10)
41
42static int oneone;
43
44static int apc_all(void * cls,
45 const struct sockaddr * addr,
46 socklen_t addrlen) {
47 return MHD_YES;
48}
49
50struct CBC {
51 char * buf;
52 size_t pos;
53 size_t size;
54};
55
56static size_t copyBuffer(void * ptr,
57 size_t size,
58 size_t nmemb,
59 void * ctx) {
60 return size * nmemb;
61}
62
63static int ahc_echo(void * cls,
64 struct MHD_Connection * connection,
65 const char * url,
66 const char * method,
67 const char * version,
68 const char * upload_data,
69 unsigned int * upload_data_size) {
70 const char * me = cls;
71 struct MHD_Response * response;
72 int ret;
73
74 if (0 != strcmp(me, method))
75 return MHD_NO; /* unexpected method */
76 response = MHD_create_response_from_data(strlen(url),
77 (void*) url,
78 MHD_NO,
79 MHD_YES);
80 ret = MHD_queue_response(connection,
81 MHD_HTTP_OK,
82 response);
83 MHD_destroy_response(response);
84 return ret;
85}
86
87
88static int testLongUrlGet() {
89 struct MHD_Daemon * d;
90 CURL * c;
91 char buf[2048];
92 struct CBC cbc;
93 char * url;
94 long code;
95
96 cbc.buf = buf;
97 cbc.size = 2048;
98 cbc.pos = 0;
99 d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */,
100 1080,
101 &apc_all,
102 NULL,
103 &ahc_echo,
104 "GET",
105 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
106 VERY_LONG / 2,
107 MHD_OPTION_END);
108 if (d == NULL)
109 return 1;
110 c = curl_easy_init();
111 url = malloc(VERY_LONG);
112 memset(url,
113 'a',
114 VERY_LONG);
115 url[VERY_LONG-1] = '\0';
116 memcpy(url,
117 "http://localhost:1080/",
118 strlen("http://localhost:1080/"));
119 curl_easy_setopt(c,
120 CURLOPT_URL,
121 url);
122 curl_easy_setopt(c,
123 CURLOPT_WRITEFUNCTION,
124 &copyBuffer);
125 curl_easy_setopt(c,
126 CURLOPT_WRITEDATA,
127 &cbc);
128 curl_easy_setopt(c,
129 CURLOPT_FAILONERROR,
130 1);
131 curl_easy_setopt(c,
132 CURLOPT_TIMEOUT,
133 2L);
134 curl_easy_setopt(c,
135 CURLOPT_CONNECTTIMEOUT,
136 2L);
137 if (oneone)
138 curl_easy_setopt(c,
139 CURLOPT_HTTP_VERSION,
140 CURL_HTTP_VERSION_1_1);
141 else
142 curl_easy_setopt(c,
143 CURLOPT_HTTP_VERSION,
144 CURL_HTTP_VERSION_1_0);
145 // NOTE: use of CONNECTTIMEOUT without also
146 // setting NOSIGNAL results in really weird
147 // crashes on my system!
148 curl_easy_setopt(c,
149 CURLOPT_NOSIGNAL,
150 1);
151 if (CURLE_OK == curl_easy_perform(c)) {
152 curl_easy_cleanup(c);
153 MHD_stop_daemon(d);
154 free(url);
155 return 2;
156 }
157 if (CURLE_OK != curl_easy_getinfo(c,
158 CURLINFO_RESPONSE_CODE,
159 &code)) {
160 curl_easy_cleanup(c);
161 MHD_stop_daemon(d);
162 free(url);
163 return 4;
164 }
165 curl_easy_cleanup(c);
166 MHD_stop_daemon(d);
167 free(url);
168 if (code != MHD_HTTP_REQUEST_URI_TOO_LONG)
169 return 8;
170 return 0;
171}
172
173
174static int testLongHeaderGet() {
175 struct MHD_Daemon * d;
176 CURL * c;
177 char buf[2048];
178 struct CBC cbc;
179 char * url;
180 long code;
181 struct curl_slist * header = NULL;
182
183 cbc.buf = buf;
184 cbc.size = 2048;
185 cbc.pos = 0;
186 d = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */,
187 1080,
188 &apc_all,
189 NULL,
190 &ahc_echo,
191 "GET",
192 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
193 VERY_LONG / 2,
194 MHD_OPTION_END);
195 if (d == NULL)
196 return 16;
197 c = curl_easy_init();
198 url = malloc(VERY_LONG);
199 memset(url,
200 'a',
201 VERY_LONG);
202 url[VERY_LONG-1] = '\0';
203 url[VERY_LONG/2] = ':';
204 url[VERY_LONG/2+1] = ':';
205 header = curl_slist_append(header,
206 url);
207
208 curl_easy_setopt(c,
209 CURLOPT_HTTPHEADER,
210 header);
211 curl_easy_setopt(c,
212 CURLOPT_URL,
213 "http://localhost:1080/hello_world");
214 curl_easy_setopt(c,
215 CURLOPT_WRITEFUNCTION,
216 &copyBuffer);
217 curl_easy_setopt(c,
218 CURLOPT_WRITEDATA,
219 &cbc);
220 curl_easy_setopt(c,
221 CURLOPT_FAILONERROR,
222 1);
223 curl_easy_setopt(c,
224 CURLOPT_TIMEOUT,
225 2L);
226 curl_easy_setopt(c,
227 CURLOPT_CONNECTTIMEOUT,
228 2L);
229 if (oneone)
230 curl_easy_setopt(c,
231 CURLOPT_HTTP_VERSION,
232 CURL_HTTP_VERSION_1_1);
233 else
234 curl_easy_setopt(c,
235 CURLOPT_HTTP_VERSION,
236 CURL_HTTP_VERSION_1_0);
237 // NOTE: use of CONNECTTIMEOUT without also
238 // setting NOSIGNAL results in really weird
239 // crashes on my system!
240 curl_easy_setopt(c,
241 CURLOPT_NOSIGNAL,
242 1);
243 if (CURLE_OK == curl_easy_perform(c)) {
244 curl_easy_cleanup(c);
245 MHD_stop_daemon(d);
246 curl_slist_free_all(header);
247 free(url);
248 return 32;
249 }
250 if (CURLE_OK != curl_easy_getinfo(c,
251 CURLINFO_RESPONSE_CODE,
252 &code)) {
253 curl_slist_free_all(header);
254 curl_easy_cleanup(c);
255 MHD_stop_daemon(d);
256 free(url);
257 return 64;
258 }
259 curl_slist_free_all(header);
260 curl_easy_cleanup(c);
261 MHD_stop_daemon(d);
262 free(url);
263 if (code != MHD_HTTP_REQUEST_ENTITY_TOO_LARGE)
264 return 128;
265 return 0;
266}
267
268
269
270
271
272int main(int argc,
273 char * const * argv) {
274 unsigned int errorCount = 0;
275
276 oneone = NULL != strstr(argv[0], "11");
277 if (0 != curl_global_init(CURL_GLOBAL_WIN32))
278 return 2;
279 errorCount += testLongUrlGet();
280 errorCount += testLongHeaderGet();
281 if (errorCount != 0)
282 fprintf(stderr,
283 "Error (code: %u)\n",
284 errorCount);
285 curl_global_cleanup();
286 return errorCount != 0; /* 0 == pass */
287}