xref: /lighttpd1.4/src/t/test_request.c (revision f3052d6a)
1 #include "first.h"
2 
3 #undef NDEBUG
4 #include <assert.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 
9 #include "request.c"
10 #include "fdlog.h"
11 
test_request_reset(request_st * const r)12 static void test_request_reset(request_st * const r)
13 {
14     r->http_method = HTTP_METHOD_UNSET;
15     r->http_version = HTTP_VERSION_UNSET;
16     r->http_host = NULL;
17     r->rqst_htags = 0;
18     r->reqbody_length = 0;
19     buffer_clear(&r->target_orig);
20     buffer_clear(&r->target);
21     array_reset_data_strings(&r->rqst_headers);
22 }
23 
run_http_request_parse(request_st * const r,int line,int status,const char * desc,const char * req,size_t reqlen)24 static void run_http_request_parse(request_st * const r, int line, int status, const char *desc, const char *req, size_t reqlen)
25 {
26     unsigned short hloffsets[32];
27     char hdrs[1024];
28     test_request_reset(r);
29     assert(reqlen < sizeof(hdrs));
30     memcpy(hdrs, req, reqlen);
31     hloffsets[0] = 1;
32     hloffsets[1] = 0;
33     hloffsets[2] = 0;
34     for (const char *n=req, *end=req+reqlen; (n=memchr(n,'\n',end-n)); ++n) {
35         if (++hloffsets[0] >= sizeof(hloffsets)/sizeof(*hloffsets)) break;
36         hloffsets[hloffsets[0]] = n - req + 1;
37     }
38     --hloffsets[0]; /*(ignore final blank line "\r\n" ending headers)*/
39     const int proto_default_port = 80;
40     int http_status =
41       http_request_parse_hoff(r, hdrs, hloffsets, proto_default_port);
42     if (http_status != status) {
43         fprintf(stderr,
44                 "%s.%d: %s() failed: expected '%d', got '%d' for test %s\n",
45                 __FILE__, line, "http_request_parse_hoff", status, http_status,
46                 desc);
47         fflush(stderr);
48         abort();
49     }
50 }
51 
test_request_http_request_parse(request_st * const r)52 static void test_request_http_request_parse(request_st * const r)
53 {
54     buffer *b;
55 
56     run_http_request_parse(r, __LINE__, 400,
57       "invalid request-line: space",
58       CONST_STR_LEN(" \r\n"
59                     "Host: www.example.org\r\n"
60                     "\r\n"));
61 
62     run_http_request_parse(r, __LINE__, 400,
63       "invalid request-line: space, char",
64       CONST_STR_LEN(" a\r\n"
65                     "Host: www.example.org\r\n"
66                     "\r\n"));
67 
68     run_http_request_parse(r, __LINE__, 400,
69       "invalid request-line: dot",
70       CONST_STR_LEN(".\r\n"
71                     "Host: www.example.org\r\n"
72                     "\r\n"));
73 
74     run_http_request_parse(r, __LINE__, 400,
75       "invalid request-line: single char",
76       CONST_STR_LEN("a\r\n"
77                     "Host: www.example.org\r\n"
78                     "\r\n"));
79 
80     run_http_request_parse(r, __LINE__, 400,
81       "invalid request-line: char, space",
82       CONST_STR_LEN("a \r\n"
83                     "Host: www.example.org\r\n"
84                     "\r\n"));
85 
86     run_http_request_parse(r, __LINE__, 400,
87       "invalid request-line: method only",
88       CONST_STR_LEN("GET\r\n"
89                     "Host: www.example.org\r\n"
90                     "\r\n"));
91 
92     run_http_request_parse(r, __LINE__, 400,
93       "invalid request-line: method space",
94       CONST_STR_LEN("GET \r\n"
95                     "Host: www.example.org\r\n"
96                     "\r\n"));
97 
98     run_http_request_parse(r, __LINE__, 400,
99       "invalid request-line: method space space",
100       CONST_STR_LEN("GET  \r\n"
101                     "Host: www.example.org\r\n"
102                     "\r\n"));
103 
104     run_http_request_parse(r, __LINE__, 400,
105       "invalid request-line: method space proto",
106       CONST_STR_LEN("GET HTTP/1.0\r\n"
107                     "Host: www.example.org\r\n"
108                     "\r\n"));
109 
110     run_http_request_parse(r, __LINE__, 400,
111       "invalid request-line: method space space proto",
112       CONST_STR_LEN("GET  HTTP/1.0\r\n"
113                     "Host: www.example.org\r\n"
114                     "\r\n"));
115 
116     run_http_request_parse(r, __LINE__, 400,
117       "invalid request-line: method space space space proto",
118       CONST_STR_LEN("GET   HTTP/1.0\r\n"
119                     "Host: www.example.org\r\n"
120                     "\r\n"));
121 
122     run_http_request_parse(r, __LINE__, 400,
123       "invalid request-line: method slash proto, no spaces",
124       CONST_STR_LEN("GET/HTTP/1.0\r\n"
125                     "Host: www.example.org\r\n"
126                     "\r\n"));
127 
128     run_http_request_parse(r, __LINE__, 400,
129       "invalid request-line: method space slash proto",
130       CONST_STR_LEN("GET /HTTP/1.0\r\n"
131                     "Host: www.example.org\r\n"
132                     "\r\n"));
133 
134     run_http_request_parse(r, __LINE__, 400,
135       "invalid request-line: method space space slash proto",
136       CONST_STR_LEN("GET  /HTTP/1.0\r\n"
137                     "Host: www.example.org\r\n"
138                     "\r\n"));
139 
140     run_http_request_parse(r, __LINE__, 501,
141       "invalid request-line: method slash space proto",
142       CONST_STR_LEN("GET/ HTTP/1.0\r\n"
143                     "Host: www.example.org\r\n"
144                     "\r\n"));
145 
146     run_http_request_parse(r, __LINE__, 501,
147       "invalid request-line: method slash space space proto",
148       CONST_STR_LEN("GET/  HTTP/1.0\r\n"
149                     "Host: www.example.org\r\n"
150                     "\r\n"));
151 
152     run_http_request_parse(r, __LINE__, 0,
153       "hostname",
154       CONST_STR_LEN("GET / HTTP/1.0\r\n"
155                     "Host: www.example.org\r\n"
156                     "\r\n"));
157     assert(r->http_host && buffer_eq_slen(r->http_host, CONST_STR_LEN("www.example.org")));
158 
159     run_http_request_parse(r, __LINE__, 0,
160       "IPv4 address",
161       CONST_STR_LEN("GET / HTTP/1.0\r\n"
162                     "Host: 127.0.0.1\r\n"
163                     "\r\n"));
164     assert(r->http_host && buffer_eq_slen(r->http_host, CONST_STR_LEN("127.0.0.1")));
165 
166     run_http_request_parse(r, __LINE__, 0,
167       "IPv6 address",
168       CONST_STR_LEN("GET / HTTP/1.0\r\n"
169                     "Host: [::1]\r\n"
170                     "\r\n"));
171     assert(r->http_host && buffer_eq_slen(r->http_host, CONST_STR_LEN("[::1]")));
172 
173     run_http_request_parse(r, __LINE__, 0,
174       "hostname + port",
175       CONST_STR_LEN("GET / HTTP/1.0\r\n"
176                     "Host: www.example.org:80\r\n"
177                     "\r\n"));
178     assert(r->http_host && buffer_eq_slen(r->http_host, CONST_STR_LEN("www.example.org")));
179 
180     run_http_request_parse(r, __LINE__, 0,
181       "IPv4 address + port",
182       CONST_STR_LEN("GET / HTTP/1.0\r\n"
183                     "Host: 127.0.0.1:80\r\n"
184                     "\r\n"));
185     assert(r->http_host && buffer_eq_slen(r->http_host, CONST_STR_LEN("127.0.0.1")));
186 
187     run_http_request_parse(r, __LINE__, 0,
188       "IPv6 address + port",
189       CONST_STR_LEN("GET / HTTP/1.0\r\n"
190                     "Host: [::1]:80\r\n"
191                     "\r\n"));
192     assert(r->http_host && buffer_eq_slen(r->http_host, CONST_STR_LEN("[::1]")));
193 
194     run_http_request_parse(r, __LINE__, 400,
195       "directory traversal",
196       CONST_STR_LEN("GET / HTTP/1.0\r\n"
197                     "Host: ../123.org\r\n"
198                     "\r\n"));
199 
200     run_http_request_parse(r, __LINE__, 400,
201       "leading and trailing dot",
202       CONST_STR_LEN("GET / HTTP/1.0\r\n"
203                     "Host: .jsdh.sfdg.sdfg.\r\n"
204                     "\r\n"));
205 
206     run_http_request_parse(r, __LINE__, 0,
207       "trailing dot is ok",
208       CONST_STR_LEN("GET / HTTP/1.0\r\n"
209                     "Host: jsdh.sfdg.sdfg.\r\n"
210                     "\r\n"));
211     assert(r->http_host && buffer_eq_slen(r->http_host, CONST_STR_LEN("jsdh.sfdg.sdfg")));
212 
213     run_http_request_parse(r, __LINE__, 400,
214       "leading dot",
215       CONST_STR_LEN("GET / HTTP/1.0\r\n"
216                     "Host: .jsdh.sfdg.sdfg\r\n"
217                     "\r\n"));
218 
219     run_http_request_parse(r, __LINE__, 400,
220       "two dots",
221       CONST_STR_LEN("GET / HTTP/1.0\r\n"
222                     "Host: jsdh..sfdg.sdfg\r\n"
223                     "\r\n"));
224 
225     run_http_request_parse(r, __LINE__, 400,
226       "broken port-number",
227       CONST_STR_LEN("GET / HTTP/1.0\r\n"
228                     "Host: jsdh.sfdg.sdfg:asd\r\n"
229                     "\r\n"));
230 
231     run_http_request_parse(r, __LINE__, 400,
232       "negative port-number",
233       CONST_STR_LEN("GET / HTTP/1.0\r\n"
234                     "Host: jsdh.sfdg.sdfg:-1\r\n"
235                     "\r\n"));
236 
237     run_http_request_parse(r, __LINE__, 400,
238       "port given but host missing",
239       CONST_STR_LEN("GET / HTTP/1.0\r\n"
240                     "Host: :80\r\n"
241                     "\r\n"));
242 
243     run_http_request_parse(r, __LINE__, 400,
244       "port and host are broken",
245       CONST_STR_LEN("GET / HTTP/1.0\r\n"
246                     "Host: .jsdh.sfdg.:sdfg.\r\n"
247                     "\r\n"));
248 
249     run_http_request_parse(r, __LINE__, 0,
250       "allowed characters in host-name",
251       CONST_STR_LEN("GET / HTTP/1.0\r\n"
252                     "Host: a.b-c.d123\r\n"
253                     "\r\n"));
254     assert(r->http_host && buffer_eq_slen(r->http_host, CONST_STR_LEN("a.b-c.d123")));
255 
256     run_http_request_parse(r, __LINE__, 400,
257       "leading dash",
258       CONST_STR_LEN("GET / HTTP/1.0\r\n"
259                     "Host: -a.c\r\n"
260                     "\r\n"));
261 
262     run_http_request_parse(r, __LINE__, 400,
263       "dot only",
264       CONST_STR_LEN("GET / HTTP/1.0\r\n"
265                     "Host: .\r\n"
266                     "\r\n"));
267 
268     run_http_request_parse(r, __LINE__, 400,
269       "broken IPv4 address - non-digit",
270       CONST_STR_LEN("GET / HTTP/1.0\r\n"
271                     "Host: a192.168.2.10:1234\r\n"
272                     "\r\n"));
273 
274     run_http_request_parse(r, __LINE__, 400,
275       "broken IPv4 address - too short",
276       CONST_STR_LEN("GET / HTTP/1.0\r\n"
277                     "Host: 192.168.2:1234\r\n"
278                     "\r\n"));
279 
280     run_http_request_parse(r, __LINE__, 400,
281       "IPv6 address + SQL injection",
282       CONST_STR_LEN("GET / HTTP/1.0\r\n"
283                     "Host: [::1]' UNION SELECT '/\r\n"
284                     "\r\n"));
285 
286     run_http_request_parse(r, __LINE__, 400,
287       "IPv6 address + path traversal",
288       CONST_STR_LEN("GET / HTTP/1.0\r\n"
289                     "Host: [::1]/../../../\r\n"
290                     "\r\n"));
291 
292     run_http_request_parse(r, __LINE__, 400,
293       "negative Content-Length",
294       CONST_STR_LEN("POST /12345.txt HTTP/1.0\r\n"
295                     "Content-Length: -2\r\n"
296                     "\r\n"));
297 
298     run_http_request_parse(r, __LINE__, 411,
299       "Content-Length is empty",
300       CONST_STR_LEN("POST /12345.txt HTTP/1.0\r\n"
301                     "Host: 123.example.org\r\n"
302                     "Content-Length:\r\n"
303                     "\r\n"));
304 
305     run_http_request_parse(r, __LINE__, 400,
306       "Host missing",
307       CONST_STR_LEN("GET / HTTP/1.1\r\n"
308                     "\r\n"));
309 
310     run_http_request_parse(r, __LINE__, 400,
311       "empty request-URI",
312       CONST_STR_LEN("GET  HTTP/1.0\r\n"
313                     "\r\n"));
314 
315     run_http_request_parse(r, __LINE__, 0,
316       "URL-decode request-URI",
317       CONST_STR_LEN("GET /index%2ehtml HTTP/1.0\r\n"
318                     "\r\n"));
319     assert(buffer_eq_slen(&r->uri.path, CONST_STR_LEN("/index.html")));
320 
321     run_http_request_parse(r, __LINE__, 0,
322       "#1232 - duplicate headers with line-wrapping",
323       CONST_STR_LEN("GET / HTTP/1.0\r\n"
324                     "Location: foo\r\n"
325                     "Location: foobar\r\n"
326                     "  baz\r\n"
327                     "\r\n"));
328     b = http_header_request_get(r, HTTP_HEADER_LOCATION,
329                                    CONST_STR_LEN("Location"));
330     assert(b && buffer_eq_slen(b, CONST_STR_LEN("foo, foobar    baz")));
331 
332     run_http_request_parse(r, __LINE__, 0,
333       "#1232 - duplicate headers with line-wrapping - test 2",
334       CONST_STR_LEN("GET / HTTP/1.0\r\n"
335                     "Location: \r\n"
336                     "Location: foobar\r\n"
337                     "  baz\r\n"
338                     "\r\n"));
339     b = http_header_request_get(r, HTTP_HEADER_LOCATION,
340                                    CONST_STR_LEN("Location"));
341     assert(b && buffer_eq_slen(b, CONST_STR_LEN("foobar    baz")));
342 
343     run_http_request_parse(r, __LINE__, 0,
344       "#1232 - duplicate headers with line-wrapping - test 3",
345       CONST_STR_LEN("GET / HTTP/1.0\r\n"
346                     "A: \r\n"
347                     "Location: foobar\r\n"
348                     "  baz\r\n"
349                     "\r\n"));
350     b = http_header_request_get(r, HTTP_HEADER_LOCATION,
351                                    CONST_STR_LEN("Location"));
352     assert(b && buffer_eq_slen(b, CONST_STR_LEN("foobar    baz")));
353 
354     run_http_request_parse(r, __LINE__, 400,
355       "missing protocol",
356       CONST_STR_LEN("GET /\r\n"
357                     "\r\n"));
358 
359     run_http_request_parse(r, __LINE__, 505,
360       "zeros in protocol version",
361       CONST_STR_LEN("GET / HTTP/01.01\r\n"
362                     "Host: foo\r\n"
363                     "\r\n"));
364 
365     run_http_request_parse(r, __LINE__, 505,
366       "missing major version",
367       CONST_STR_LEN("GET / HTTP/.01\r\n"
368                     "\r\n"));
369 
370     run_http_request_parse(r, __LINE__, 505,
371       "missing minor version",
372       CONST_STR_LEN("GET / HTTP/01.\r\n"
373                     "\r\n"));
374 
375     run_http_request_parse(r, __LINE__, 505,
376       "strings as version",
377       CONST_STR_LEN("GET / HTTP/a.b\r\n"
378                     "\r\n"));
379 
380     run_http_request_parse(r, __LINE__, 400,
381       "missing protocol + unknown method",
382       CONST_STR_LEN("BC /\r\n"
383                     "\r\n"));
384 
385     run_http_request_parse(r, __LINE__, 400,
386       "missing protocol + unknown method + missing URI",
387       CONST_STR_LEN("ABC\r\n"
388                     "\r\n"));
389 
390     run_http_request_parse(r, __LINE__, 501,
391       "unknown method",
392       CONST_STR_LEN("ABC / HTTP/1.0\r\n"
393                     "\r\n"));
394 
395     run_http_request_parse(r, __LINE__, 505,
396       "unknown protocol",
397       CONST_STR_LEN("GET / HTTP/1.3\r\n"
398                     "\r\n"));
399 
400     run_http_request_parse(r, __LINE__, 0,
401       "absolute URI",
402       CONST_STR_LEN("GET http://www.example.org/ HTTP/1.0\r\n"
403                     "\r\n"));
404     assert(r->http_host && buffer_eq_slen(r->http_host, CONST_STR_LEN("www.example.org")));
405     assert(buffer_eq_slen(&r->target, CONST_STR_LEN("/")));
406 
407     run_http_request_parse(r, __LINE__, 400,
408       "whitespace after key",
409       CONST_STR_LEN("GET / HTTP/1.0\r\n"
410                     "ABC : foo\r\n"
411                     "\r\n"));
412 
413     run_http_request_parse(r, __LINE__, 400,
414       "whitespace within key",
415       CONST_STR_LEN("GET / HTTP/1.0\r\n"
416                     "ABC a: foo\r\n"
417                     "\r\n"));
418 
419     run_http_request_parse(r, __LINE__, 0,
420       "no whitespace",
421       CONST_STR_LEN("GET / HTTP/1.0\r\n"
422                     "ABC:foo\r\n"
423                     "\r\n"));
424     b = http_header_request_get(r, HTTP_HEADER_OTHER, CONST_STR_LEN("ABC"));
425     assert(b && buffer_eq_slen(b, CONST_STR_LEN("foo")));
426 
427     run_http_request_parse(r, __LINE__, 0,
428       "line-folding",
429       CONST_STR_LEN("GET / HTTP/1.0\r\n"
430                     "ABC:foo\r\n"
431                     "  bc\r\n"
432                     "\r\n"));
433     b = http_header_request_get(r, HTTP_HEADER_OTHER, CONST_STR_LEN("ABC"));
434     assert(b && buffer_eq_slen(b, CONST_STR_LEN("foo    bc")));
435 
436     run_http_request_parse(r, __LINE__, 411,
437       "POST request, no Content-Length",
438       CONST_STR_LEN("POST / HTTP/1.0\r\n"
439                     "\r\n"));
440 
441     run_http_request_parse(r, __LINE__, 400,
442       "Duplicate Host headers, Bug #25",
443       CONST_STR_LEN("GET / HTTP/1.0\r\n"
444                     "Host: www.example.org\r\n"
445                     "Host: 123.example.org\r\n"
446                     "\r\n"));
447 
448     run_http_request_parse(r, __LINE__, 400,
449       "Duplicate Content-Length headers",
450       CONST_STR_LEN("GET / HTTP/1.0\r\n"
451                     "Content-Length: 5\r\n"
452                     "Content-Length: 4\r\n"
453                     "\r\n"));
454 
455     run_http_request_parse(r, __LINE__, 400,
456       "Duplicate Content-Type headers",
457       CONST_STR_LEN("GET / HTTP/1.0\r\n"
458                     "Content-Type: 5\r\n"
459                     "Content-Type: 4\r\n"
460                     "\r\n"));
461 
462     /* (not actually testing Range here anymore; parsing deferred until use) */
463 
464     run_http_request_parse(r, __LINE__, 0,
465       "Duplicate Range headers (get appended)",
466       CONST_STR_LEN("GET / HTTP/1.0\r\n"
467                     "Range: bytes=5-6\r\n"
468                     "Range: bytes=5-9\r\n"
469                     "\r\n"));
470 
471     run_http_request_parse(r, __LINE__, 0,
472       "Duplicate Range headers with invalid range (a)",
473       CONST_STR_LEN("GET / HTTP/1.0\r\n"
474                     "Range: bytes=0\r\n"
475                     "Range: bytes=5-9\r\n"
476                     "\r\n"));
477     run_http_request_parse(r, __LINE__, 0,
478       "Duplicate Range headers with invalid range (b)",
479       CONST_STR_LEN("GET / HTTP/1.0\r\n"
480                     "Range: bytes=5-9\r\n"
481                     "Range: bytes=0\r\n"
482                     "\r\n"));
483     run_http_request_parse(r, __LINE__, 0,
484       "Duplicate Range headers with invalid range (c)",
485       CONST_STR_LEN("GET / HTTP/1.0\r\n"
486                     "Range: 0\r\n"
487                     "Range: bytes=5-9\r\n"
488                     "\r\n"));
489     run_http_request_parse(r, __LINE__, 0,
490       "Duplicate Range headers with invalid range (d)",
491       CONST_STR_LEN("GET / HTTP/1.0\r\n"
492                     "Range: bytes=5-9\r\n"
493                     "Range: 0\r\n"
494                     "\r\n"));
495 
496     run_http_request_parse(r, __LINE__, 0,
497       "Duplicate If-None-Match headers",
498       CONST_STR_LEN("GET / HTTP/1.0\r\n"
499                     "If-None-Match: 5\r\n"
500                     "If-None-Match: 4\r\n"
501                     "\r\n"));
502 
503     run_http_request_parse(r, __LINE__, 400,
504       "Duplicate If-Modified-Since headers",
505       CONST_STR_LEN("GET / HTTP/1.0\r\n"
506                     "If-Modified-Since: 5\r\n"
507                     "If-Modified-Since: 4\r\n"
508                     "\r\n"));
509 
510     run_http_request_parse(r, __LINE__, 400,
511       "GET with Content-Length",
512       CONST_STR_LEN("GET / HTTP/1.0\r\n"
513                     "Content-Length: 4\r\n"
514                     "\r\n"
515                     "1234"));
516 
517     run_http_request_parse(r, __LINE__, 400,
518       "HEAD with Content-Length",
519       CONST_STR_LEN("HEAD / HTTP/1.0\r\n"
520                     "Content-Length: 4\r\n"
521                     "\r\n"
522                     "1234"));
523 
524     run_http_request_parse(r, __LINE__, 400,
525       "invalid chars in Header values (bug #1286)",
526       CONST_STR_LEN("GET / HTTP/1.0\r\n"
527                     "If-Modified-Since: \0\r\n"
528                     "\r\n"));
529 
530     run_http_request_parse(r, __LINE__, 0,
531       "absolute-uri in request-line (without Host)",
532       CONST_STR_LEN("GET http://zzz.example.org/ HTTP/1.1\r\n"
533                     "Connection: close\r\n"
534                     "\r\n"));
535     b = http_header_request_get(r, HTTP_HEADER_HOST, CONST_STR_LEN("Host"));
536     assert(b && buffer_eq_slen(b, CONST_STR_LEN("zzz.example.org")));
537 
538     run_http_request_parse(r, __LINE__, 0,
539       "absolute-uri in request-line (with Host match)",
540       CONST_STR_LEN("GET http://zzz.example.org/ HTTP/1.1\r\n"
541                     "Host: zzz.example.org\r\n"
542                     "Connection: close\r\n"
543                     "\r\n"));
544     b = http_header_request_get(r, HTTP_HEADER_HOST, CONST_STR_LEN("Host"));
545     assert(b && buffer_eq_slen(b, CONST_STR_LEN("zzz.example.org")));
546 
547     run_http_request_parse(r, __LINE__, 400,
548       "absolute-uri in request-line (with Host mismatch)",
549       CONST_STR_LEN("GET http://zzz.example.org/ HTTP/1.1\r\n"
550                     "Host: aaa.example.org\r\n"
551                     "Connection: close\r\n"
552                     "\r\n"));
553 
554     run_http_request_parse(r, __LINE__, 0,
555       "ignore duplicated If-Modified-Since if matching",
556       CONST_STR_LEN("GET / HTTP/1.1\r\n"
557                     "Host: zzz.example.org\r\n"
558                     "If-Modified-Since: Sun, 01 Jan 2036 00:00:02 GMT\r\n"
559                     "If-Modified-Since: Sun, 01 Jan 2036 00:00:02 GMT\r\n"
560                     "Connection: close\r\n"
561                     "\r\n"));
562     b = http_header_request_get(r, HTTP_HEADER_IF_MODIFIED_SINCE,
563                                 CONST_STR_LEN("If-Modified-Since"));
564     assert(b && buffer_eq_slen(b,
565                                CONST_STR_LEN("Sun, 01 Jan 2036 00:00:02 GMT")));
566 
567     run_http_request_parse(r, __LINE__, 400,
568       "reject duplicated If-Modified-Since if not matching",
569       CONST_STR_LEN("GET / HTTP/1.1\r\n"
570                     "Host: zzz.example.org\r\n"
571                     "If-Modified-Since: Sun, 01 Jan 2036 00:00:02 GMT\r\n"
572                     "If-Modified-Since: Sun, 01 Jan 2036 00:00:03 GMT\r\n"
573                     "Connection: close\r\n"
574                     "\r\n"));
575 
576     run_http_request_parse(r, __LINE__, 0,
577       "large headers", /*(copied from tests/request.t)*/
578       CONST_STR_LEN("GET / HTTP/1.0\r\n"
579                     "Hsgfsdjf: asdfhdf\r\n"
580                     "hdhd: shdfhfdasd\r\n"
581                     "hfhr: jfghsdfg\r\n"
582                     "jfuuehdmn: sfdgjfdg\r\n"
583                     "jvcbzufdg: sgfdfg\r\n"
584                     "hrnvcnd: jfjdfg\r\n"
585                     "jfusfdngmd: gfjgfdusdfg\r\n"
586                     "nfj: jgfdjdfg\r\n"
587                     "jfue: jfdfdg\r\n"
588                     "\r\n"));
589 
590     /* (quick check that none of above tests were left in a state
591      *  which resulted in subsequent tests returning 400 for other
592      *  reasons) */
593     run_http_request_parse(r, __LINE__, 0,
594       "valid",
595       CONST_STR_LEN("GET / HTTP/1.0\r\n"
596                     "Host: www.example.org\r\n"
597                     "\r\n"));
598 }
599 
600 #include "base.h"
601 #include "burl.h"
602 #include "log.h"
603 
604 void test_request (void);
test_request(void)605 void test_request (void)
606 {
607     request_st r;
608 
609     memset(&r, 0, sizeof(request_st));
610     r.conf.errh              = fdlog_init(NULL, -1, FDLOG_FD);
611     r.conf.errh->fd          = -1; /* (disable) */
612     r.conf.allow_http11      = 1;
613     r.conf.http_parseopts    = HTTP_PARSEOPT_HEADER_STRICT
614                              | HTTP_PARSEOPT_HOST_STRICT
615                              | HTTP_PARSEOPT_HOST_NORMALIZE;
616 
617     test_request_http_request_parse(&r);
618 
619     free(r.target_orig.ptr);
620     free(r.target.ptr);
621     free(r.uri.authority.ptr);
622     free(r.uri.path.ptr);
623     free(r.uri.scheme.ptr);
624     array_free_data(&r.rqst_headers);
625 
626     fdlog_free(r.conf.errh);
627 }
628