aboutsummaryrefslogtreecommitdiff
path: root/src/testcurl/test_long_header.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testcurl/test_long_header.c')
-rw-r--r--src/testcurl/test_long_header.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/src/testcurl/test_long_header.c b/src/testcurl/test_long_header.c
new file mode 100644
index 00000000..4df2c6da
--- /dev/null
+++ b/src/testcurl/test_long_header.c
@@ -0,0 +1,252 @@
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 "MHD_config.h"
28#include "platform.h"
29#include <curl/curl.h>
30#include <microhttpd.h>
31#include <stdlib.h>
32#include <string.h>
33#include <time.h>
34
35#ifndef WINDOWS
36#include <unistd.h>
37#endif
38
39/**
40 * We will set the memory available per connection to
41 * half of this value, so the actual value does not have
42 * to be big at all...
43 */
44#define VERY_LONG (1024*10)
45
46static int oneone;
47
48static int
49apc_all (void *cls, const struct sockaddr *addr, socklen_t addrlen)
50{
51 return MHD_YES;
52}
53
54struct CBC
55{
56 char *buf;
57 size_t pos;
58 size_t size;
59};
60
61static size_t
62copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
63{
64 return size * nmemb;
65}
66
67static int
68ahc_echo (void *cls,
69 struct MHD_Connection *connection,
70 const char *url,
71 const char *method,
72 const char *version,
73 const char *upload_data, size_t *upload_data_size,
74 void **unused)
75{
76 const char *me = cls;
77 struct MHD_Response *response;
78 int ret;
79
80 if (0 != strcmp (me, method))
81 return MHD_NO; /* unexpected method */
82 response = MHD_create_response_from_buffer (strlen (url),
83 (void *) url,
84 MHD_RESPMEM_MUST_COPY);
85 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
86 MHD_destroy_response (response);
87 return ret;
88}
89
90
91static int
92testLongUrlGet ()
93{
94 struct MHD_Daemon *d;
95 CURL *c;
96 char buf[2048];
97 struct CBC cbc;
98 char *url;
99 long code;
100
101 cbc.buf = buf;
102 cbc.size = 2048;
103 cbc.pos = 0;
104 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */ ,
105 1080,
106 &apc_all,
107 NULL,
108 &ahc_echo,
109 "GET",
110 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
111 (size_t) (VERY_LONG / 2), MHD_OPTION_END);
112 if (d == NULL)
113 return 1;
114 c = curl_easy_init ();
115 url = malloc (VERY_LONG);
116 if (url == NULL)
117 {
118 MHD_stop_daemon (d);
119 return 1;
120 }
121 memset (url, 'a', VERY_LONG);
122 url[VERY_LONG - 1] = '\0';
123 memcpy (url, "http://127.0.0.1:1080/", strlen ("http://127.0.0.1:1080/"));
124 curl_easy_setopt (c, CURLOPT_URL, url);
125 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
126 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
127 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
128 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
129 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
130 if (oneone)
131 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
132 else
133 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
134 /* NOTE: use of CONNECTTIMEOUT without also
135 setting NOSIGNAL results in really weird
136 crashes on my system! */
137 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
138 if (CURLE_OK == curl_easy_perform (c))
139 {
140 curl_easy_cleanup (c);
141 MHD_stop_daemon (d);
142 free (url);
143 return 2;
144 }
145 if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
146 {
147 curl_easy_cleanup (c);
148 MHD_stop_daemon (d);
149 free (url);
150 return 4;
151 }
152 curl_easy_cleanup (c);
153 MHD_stop_daemon (d);
154 free (url);
155 if (code != MHD_HTTP_REQUEST_URI_TOO_LONG)
156 return 8;
157 return 0;
158}
159
160
161static int
162testLongHeaderGet ()
163{
164 struct MHD_Daemon *d;
165 CURL *c;
166 char buf[2048];
167 struct CBC cbc;
168 char *url;
169 long code;
170 struct curl_slist *header = NULL;
171
172 cbc.buf = buf;
173 cbc.size = 2048;
174 cbc.pos = 0;
175 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY /* | MHD_USE_DEBUG */ ,
176 1080,
177 &apc_all,
178 NULL,
179 &ahc_echo,
180 "GET",
181 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
182 (size_t) (VERY_LONG / 2), MHD_OPTION_END);
183 if (d == NULL)
184 return 16;
185 c = curl_easy_init ();
186 url = malloc (VERY_LONG);
187 if (url == NULL)
188 {
189 MHD_stop_daemon (d);
190 return 16;
191 }
192 memset (url, 'a', VERY_LONG);
193 url[VERY_LONG - 1] = '\0';
194 url[VERY_LONG / 2] = ':';
195 url[VERY_LONG / 2 + 1] = ' ';
196 header = curl_slist_append (header, url);
197
198 curl_easy_setopt (c, CURLOPT_HTTPHEADER, header);
199 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1080/hello_world");
200 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
201 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
202 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
203 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
204 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
205 if (oneone)
206 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
207 else
208 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
209 /* NOTE: use of CONNECTTIMEOUT without also
210 setting NOSIGNAL results in really weird
211 crashes on my system! */
212 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
213 if (CURLE_OK == curl_easy_perform (c))
214 {
215 curl_easy_cleanup (c);
216 MHD_stop_daemon (d);
217 curl_slist_free_all (header);
218 free (url);
219 return 32;
220 }
221 if (CURLE_OK != curl_easy_getinfo (c, CURLINFO_RESPONSE_CODE, &code))
222 {
223 curl_slist_free_all (header);
224 curl_easy_cleanup (c);
225 MHD_stop_daemon (d);
226 free (url);
227 return 64;
228 }
229 curl_slist_free_all (header);
230 curl_easy_cleanup (c);
231 MHD_stop_daemon (d);
232 free (url);
233 if (code != MHD_HTTP_REQUEST_ENTITY_TOO_LARGE)
234 return 128;
235 return 0;
236}
237
238int
239main (int argc, char *const *argv)
240{
241 unsigned int errorCount = 0;
242
243 oneone = NULL != strstr (argv[0], "11");
244 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
245 return 2;
246 errorCount += testLongUrlGet ();
247 errorCount += testLongHeaderGet ();
248 if (errorCount != 0)
249 fprintf (stderr, "Error (code: %u)\n", errorCount);
250 curl_global_cleanup ();
251 return errorCount != 0; /* 0 == pass */
252}