]> git.ipfire.org Git - thirdparty/squid.git/blob - src/tests/testHttpRequest.cc
Merge from trunk
[thirdparty/squid.git] / src / tests / testHttpRequest.cc
1 #define SQUID_UNIT_TEST 1
2 #include "config.h"
3
4 #include <cppunit/TestAssert.h>
5
6 #include "testHttpRequest.h"
7 #include "HttpRequest.h"
8 #include "Mem.h"
9
10
11 CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequest );
12
13 /** wrapper for testing HttpRequest object private and protected functions */
14 class PrivateHttpRequest : public HttpRequest
15 {
16 public:
17 bool doSanityCheckStartLine(MemBuf *b, const size_t h, http_status *e) { return sanityCheckStartLine(b,h,e); };
18 };
19
20 /* init memory pools */
21
22 void
23 testHttpRequest::setUp()
24 {
25 Mem::Init();
26 httpHeaderInitModule();
27 }
28
29 /*
30 * Test creating an HttpRequest object from a Url and method
31 */
32 void
33 testHttpRequest::testCreateFromUrlAndMethod()
34 {
35 /* vanilla url */
36 ushort expected_port;
37 char * url = xstrdup("http://foo:90/bar");
38 HttpRequest *aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
39 expected_port = 90;
40 HttpRequest *nullRequest = NULL;
41 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
42 CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
43 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
44 CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
45 CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
46 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url));
47 xfree(url);
48
49 /* vanilla url, different method */
50 url = xstrdup("http://foo/bar");
51 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_PUT);
52 expected_port = 80;
53 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
54 CPPUNIT_ASSERT(aRequest->method == METHOD_PUT);
55 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
56 CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
57 CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
58 CPPUNIT_ASSERT_EQUAL(String("http://foo/bar"), String(url));
59
60 /* a connect url with non-CONNECT data */
61 url = xstrdup(":foo/bar");
62 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_CONNECT);
63 xfree(url);
64 CPPUNIT_ASSERT_EQUAL(nullRequest, aRequest);
65
66 /* a CONNECT url with CONNECT data */
67 url = xstrdup("foo:45");
68 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_CONNECT);
69 expected_port = 45;
70 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
71 CPPUNIT_ASSERT(aRequest->method == METHOD_CONNECT);
72 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
73 CPPUNIT_ASSERT_EQUAL(String(""), aRequest->urlpath);
74 CPPUNIT_ASSERT_EQUAL(PROTO_NONE, aRequest->protocol);
75 CPPUNIT_ASSERT_EQUAL(String("foo:45"), String(url));
76 xfree(url);
77 }
78
79 /*
80 * Test creating an HttpRequest object from a Url alone.
81 */
82 void
83 testHttpRequest::testCreateFromUrl()
84 {
85 /* vanilla url */
86 ushort expected_port;
87 char * url = xstrdup("http://foo:90/bar");
88 HttpRequest *aRequest = HttpRequest::CreateFromUrl(url);
89 expected_port = 90;
90 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
91 CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
92 CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
93 CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
94 CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
95 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url));
96 xfree(url);
97 }
98
99 /*
100 * Test BUG: URL '2000:800:45' opens host 2000 port 800 !!
101 */
102 void
103 testHttpRequest::testIPv6HostColonBug()
104 {
105 ushort expected_port;
106 char * url = NULL;
107 HttpRequest *aRequest = NULL;
108
109 /* valid IPv6 address without port */
110 url = xstrdup("http://[2000:800::45]/foo");
111 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
112 expected_port = 80;
113 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
114 CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
115 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
116 CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
117 CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
118 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]/foo"), String(url));
119 xfree(url);
120
121 /* valid IPv6 address with port */
122 url = xstrdup("http://[2000:800::45]:90/foo");
123 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
124 expected_port = 90;
125 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
126 CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
127 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
128 CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
129 CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
130 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]:90/foo"), String(url));
131 xfree(url);
132
133 /* IPv6 address as invalid (bug trigger) */
134 url = xstrdup("http://2000:800::45/foo");
135 aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
136 expected_port = 80;
137 CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
138 CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
139 CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
140 CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
141 CPPUNIT_ASSERT_EQUAL(PROTO_HTTP, aRequest->protocol);
142 CPPUNIT_ASSERT_EQUAL(String("http://2000:800::45/foo"), String(url));
143 xfree(url);
144 }
145
146 void
147 testHttpRequest::testSanityCheckStartLine()
148 {
149 MemBuf input;
150 PrivateHttpRequest engine;
151 http_status error = HTTP_STATUS_NONE;
152 size_t hdr_len;
153 input.init();
154
155 // a valid request line
156 input.append("GET / HTTP/1.1\n\n", 16);
157 hdr_len = headersEnd(input.content(), input.contentSize());
158 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
159 CPPUNIT_ASSERT_EQUAL(error, HTTP_STATUS_NONE);
160 input.reset();
161 error = HTTP_STATUS_NONE;
162
163 input.append("GET / HTTP/1.1\n\n", 18);
164 hdr_len = headersEnd(input.content(), input.contentSize());
165 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
166 CPPUNIT_ASSERT_EQUAL(error, HTTP_STATUS_NONE);
167 input.reset();
168 error = HTTP_STATUS_NONE;
169
170 // strange but valid methods
171 input.append(". / HTTP/1.1\n\n", 14);
172 hdr_len = headersEnd(input.content(), input.contentSize());
173 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
174 CPPUNIT_ASSERT_EQUAL(error, HTTP_STATUS_NONE);
175 input.reset();
176 error = HTTP_STATUS_NONE;
177
178 input.append("OPTIONS * HTTP/1.1\n\n", 20);
179 hdr_len = headersEnd(input.content(), input.contentSize());
180 CPPUNIT_ASSERT(engine.doSanityCheckStartLine(&input, hdr_len, &error) );
181 CPPUNIT_ASSERT_EQUAL(error, HTTP_STATUS_NONE);
182 input.reset();
183 error = HTTP_STATUS_NONE;
184
185 // TODO no method
186
187 // TODO binary code in method
188
189 // TODO no URL
190
191 // TODO no status (okay)
192
193 // TODO non-HTTP protocol
194
195 input.append(" \n\n", 8);
196 hdr_len = headersEnd(input.content(), input.contentSize());
197 CPPUNIT_ASSERT(!engine.doSanityCheckStartLine(&input, hdr_len, &error) );
198 CPPUNIT_ASSERT_EQUAL(error, HTTP_INVALID_HEADER);
199 input.reset();
200 error = HTTP_STATUS_NONE;
201 }
202
203 void
204 testHttpRequest::testParseRequestLine()
205 {
206 MemBuf input;
207 HttpParser output;
208 input.init();
209
210 // TEST: Do we comply with RFC 1945 section 5.1 ?
211 // TEST: Do we comply with RFC 2616 section 5.1 ?
212
213 // RFC 1945 : HTTP/0.9 simple-request
214 input.append("GET /\r\n", 7);
215 HttpParserInit(&output, input.content(), input.contentSize());
216 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
217 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
218 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
219 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
220 CPPUNIT_ASSERT(memcmp("GET /\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
221 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
222 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
223 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start], (output.m_end-output.m_start+1)) == 0);
224 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
225 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
226 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start], (output.u_end-output.u_start+1)) == 0);
227 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
228 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
229 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
230 CPPUNIT_ASSERT_EQUAL(9, output.v_min);
231 input.reset();
232
233 // RFC 1945 and 2616 : HTTP/1.0 full-request
234 input.append("GET / HTTP/1.0\r\n", 16);
235 HttpParserInit(&output, input.content(), input.contentSize());
236 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
237 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
238 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
239 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
240 CPPUNIT_ASSERT(memcmp("GET / HTTP/1.0\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
241 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
242 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
243 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
244 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
245 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
246 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
247 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
248 CPPUNIT_ASSERT_EQUAL(13, output.v_end);
249 CPPUNIT_ASSERT(memcmp("HTTP/1.0", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
250 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
251 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
252 input.reset();
253
254
255 // RFC 2616 : HTTP/1.1 full-request
256 input.append("GET / HTTP/1.1\r\n", 16);
257 HttpParserInit(&output, input.content(), input.contentSize());
258 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
259 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
260 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
261 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
262 CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
263 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
264 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
265 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
266 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
267 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
268 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
269 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
270 CPPUNIT_ASSERT_EQUAL(13, output.v_end);
271 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
272 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
273 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
274 input.reset();
275
276 // RFC 2616 : future version full-request
277 input.append("GET / HTTP/10.12\r\n", 18);
278 //printf("TEST: '%s'\n",input.content());
279 HttpParserInit(&output, input.content(), input.contentSize());
280 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
281 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
282 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
283 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
284 CPPUNIT_ASSERT(memcmp("GET / HTTP/10.12\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
285 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
286 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
287 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
288 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
289 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
290 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
291 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
292 CPPUNIT_ASSERT_EQUAL(15, output.v_end);
293 CPPUNIT_ASSERT(memcmp("HTTP/10.12", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
294 CPPUNIT_ASSERT_EQUAL(10, output.v_maj);
295 CPPUNIT_ASSERT_EQUAL(12, output.v_min);
296 input.reset();
297
298 // space padded URL
299 input.append("GET / HTTP/1.1\r\n", 21);
300 //printf("TEST: '%s'\n",input.content());
301 HttpParserInit(&output, input.content(), input.contentSize());
302 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
303 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
304 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
305 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
306 CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
307 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
308 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
309 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
310 CPPUNIT_ASSERT_EQUAL(5, output.u_start);
311 CPPUNIT_ASSERT_EQUAL(5, output.u_end);
312 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
313 CPPUNIT_ASSERT_EQUAL(11, output.v_start);
314 CPPUNIT_ASSERT_EQUAL(18, output.v_end);
315 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
316 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
317 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
318 input.reset();
319
320 // space padded version
321 // RFC 1945 and 2616 specify version is followed by CRLF. No intermediary bytes.
322 // NP: the terminal whitespace is a special case: invalid for even HTTP/0.9 with no version tag
323 input.append("GET / HTTP/1.1 \n", 16);
324 //printf("TEST: '%s'\n",input.content());
325 HttpParserInit(&output, input.content(), input.contentSize());
326 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
327 CPPUNIT_ASSERT_EQUAL(HTTP_BAD_REQUEST, output.request_parse_status);
328 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
329 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
330 CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1 \n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
331 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
332 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
333 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
334 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
335 CPPUNIT_ASSERT_EQUAL(13, output.u_end);
336 CPPUNIT_ASSERT(memcmp("/ HTTP/1.1", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
337 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
338 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
339 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
340 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
341 input.reset();
342
343 // whitespace inside URI. (nasty but happens)
344 input.append("GET /fo o/ HTTP/1.1\n", 20);
345 //printf("TEST: '%s'\n",input.content());
346 HttpParserInit(&output, input.content(), input.contentSize());
347 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
348 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
349 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
350 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
351 CPPUNIT_ASSERT(memcmp("GET /fo o/ HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
352 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
353 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
354 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
355 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
356 CPPUNIT_ASSERT_EQUAL(9, output.u_end);
357 CPPUNIT_ASSERT(memcmp("/fo o/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
358 CPPUNIT_ASSERT_EQUAL(11, output.v_start);
359 CPPUNIT_ASSERT_EQUAL(18, output.v_end);
360 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
361 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
362 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
363 input.reset();
364
365 // additional data in buffer
366 input.append("GET / HTTP/1.1\nboo!", 23);
367 //printf("TEST: '%s'\n",input.content());
368 HttpParserInit(&output, input.content(), input.contentSize());
369 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
370 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
371 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
372 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-5, output.req_end);
373 CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
374 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
375 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
376 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
377 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
378 CPPUNIT_ASSERT_EQUAL(4, output.u_end); // strangeness generated by following RFC
379 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
380 CPPUNIT_ASSERT_EQUAL(10, output.v_start);
381 CPPUNIT_ASSERT_EQUAL(17, output.v_end);
382 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
383 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
384 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
385 input.reset();
386
387 // alternative EOL sequence: NL-only
388 input.append("GET / HTTP/1.1\n", 15);
389 //printf("TEST: '%s'\n",input.content());
390 HttpParserInit(&output, input.content(), input.contentSize());
391 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
392 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
393 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
394 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
395 CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
396 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
397 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
398 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
399 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
400 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
401 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
402 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
403 CPPUNIT_ASSERT_EQUAL(13, output.v_end);
404 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
405 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
406 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
407 input.reset();
408
409 // alternative EOL sequence: double-NL-only
410 input.append("GET / HTTP/1.1\n\n", 16);
411 //printf("TEST: '%s'\n",input.content());
412 HttpParserInit(&output, input.content(), input.contentSize());
413 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
414 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
415 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
416 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-2, output.req_end);
417 CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
418 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
419 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
420 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
421 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
422 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
423 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
424 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
425 CPPUNIT_ASSERT_EQUAL(13, output.v_end);
426 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
427 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
428 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
429 input.reset();
430
431 // RELAXED alternative EOL sequence: multi-CR-NL
432 input.append("GET / HTTP/1.1\r\r\r\n", 18);
433 //printf("TEST: '%s'\n",input.content());
434 HttpParserInit(&output, input.content(), input.contentSize());
435 Config.onoff.relaxed_header_parser = 1;
436 // Being tolerant we can ignore and elide these apparently benign CR
437 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
438 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
439 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
440 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
441 CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\r\r\r\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
442 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
443 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
444 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
445 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
446 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
447 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
448 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
449 CPPUNIT_ASSERT_EQUAL(13, output.v_end);
450 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
451 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
452 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
453 input.reset();
454
455 // STRICT alternative EOL sequence: multi-CR-NL
456 input.append("GET / HTTP/1.1\r\r\r\n", 18);
457 //printf("TEST: '%s'\n",input.content());
458 HttpParserInit(&output, input.content(), input.contentSize());
459 // strict mode treats these as several bare-CR in the request line which is explicitly invalid.
460 Config.onoff.relaxed_header_parser = 0;
461 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
462 CPPUNIT_ASSERT_EQUAL(HTTP_BAD_REQUEST, output.request_parse_status);
463 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
464 CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
465 CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
466 CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
467 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
468 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
469 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
470 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
471 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
472 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
473 input.reset();
474
475 // RFC 2616 : . method
476 input.append(". / HTTP/1.1\n", 13);
477 //printf("TEST: '%s'\n",input.content());
478 HttpParserInit(&output, input.content(), input.contentSize());
479 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
480 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
481 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
482 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
483 CPPUNIT_ASSERT(memcmp(". / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
484 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
485 CPPUNIT_ASSERT_EQUAL(0, output.m_end);
486 CPPUNIT_ASSERT(memcmp(".", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
487 CPPUNIT_ASSERT_EQUAL(2, output.u_start);
488 CPPUNIT_ASSERT_EQUAL(2, output.u_end);
489 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
490 CPPUNIT_ASSERT_EQUAL(4, output.v_start);
491 CPPUNIT_ASSERT_EQUAL(11, output.v_end);
492 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
493 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
494 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
495 input.reset();
496
497 // OPTIONS with * URL
498 input.append("OPTIONS * HTTP/1.1\n", 19);
499 //printf("TEST: '%s'\n",input.content());
500 HttpParserInit(&output, input.content(), input.contentSize());
501 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
502 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
503 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
504 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
505 CPPUNIT_ASSERT(memcmp("OPTIONS * HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
506 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
507 CPPUNIT_ASSERT_EQUAL(6, output.m_end);
508 CPPUNIT_ASSERT(memcmp("OPTIONS", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
509 CPPUNIT_ASSERT_EQUAL(8, output.u_start);
510 CPPUNIT_ASSERT_EQUAL(8, output.u_end);
511 CPPUNIT_ASSERT(memcmp("*", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
512 CPPUNIT_ASSERT_EQUAL(10, output.v_start);
513 CPPUNIT_ASSERT_EQUAL(17, output.v_end);
514 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
515 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
516 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
517 input.reset();
518
519 // unknown method
520 input.append("HELLOWORLD / HTTP/1.1\n", 22);
521 //printf("TEST: '%s'\n",input.content());
522 HttpParserInit(&output, input.content(), input.contentSize());
523 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
524 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
525 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
526 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
527 CPPUNIT_ASSERT(memcmp("HELLOWORLD / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
528 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
529 CPPUNIT_ASSERT_EQUAL(9, output.m_end);
530 CPPUNIT_ASSERT(memcmp("HELLOWORLD", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
531 CPPUNIT_ASSERT_EQUAL(11, output.u_start);
532 CPPUNIT_ASSERT_EQUAL(11, output.u_end);
533 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
534 CPPUNIT_ASSERT_EQUAL(13, output.v_start);
535 CPPUNIT_ASSERT_EQUAL(20, output.v_end);
536 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
537 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
538 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
539 input.reset();
540
541 // This stage of the parser does not yet accept non-HTTP protocol names.
542 // violations mode treats them as HTTP/0.9 requests!
543 input.append("GET / FOO/1.0\n", 14);
544 //printf("TEST: '%s'\n",input.content());
545 HttpParserInit(&output, input.content(), input.contentSize());
546 #if USE_HTTP_VIOLATIONS
547 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
548 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
549 CPPUNIT_ASSERT_EQUAL(12, output.u_end);
550 CPPUNIT_ASSERT(memcmp("/ FOO/1.0", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
551 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
552 CPPUNIT_ASSERT_EQUAL(9, output.v_min);
553 #else
554 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
555 CPPUNIT_ASSERT_EQUAL(HTTP_HTTP_VERSION_NOT_SUPPORTED, output.request_parse_status);
556 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
557 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
558 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
559 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
560 #endif
561 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
562 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
563 CPPUNIT_ASSERT(memcmp("GET / FOO/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
564 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
565 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
566 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
567 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
568 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
569 CPPUNIT_ASSERT_EQUAL(12, output.v_end);
570 CPPUNIT_ASSERT(memcmp("FOO/1.0", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
571 input.reset();
572
573 // RELAXED space padded method (in strict mode SP is reserved so invalid as a method byte)
574 input.append(" GET / HTTP/1.1\n", 16);
575 //printf("TEST: '%s'\n",input.content());
576 HttpParserInit(&output, input.content(), input.contentSize());
577 Config.onoff.relaxed_header_parser = 1;
578 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
579 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
580 CPPUNIT_ASSERT_EQUAL(1, output.req_start);
581 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
582 CPPUNIT_ASSERT(memcmp("GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
583 CPPUNIT_ASSERT_EQUAL(1, output.m_start);
584 CPPUNIT_ASSERT_EQUAL(3, output.m_end);
585 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
586 CPPUNIT_ASSERT_EQUAL(5, output.u_start);
587 CPPUNIT_ASSERT_EQUAL(5, output.u_end);
588 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
589 CPPUNIT_ASSERT_EQUAL(7, output.v_start);
590 CPPUNIT_ASSERT_EQUAL(14, output.v_end);
591 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
592 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
593 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
594 input.reset();
595
596 // STRICT space padded method (in strict mode SP is reserved so invalid as a method byte)
597 input.append(" GET / HTTP/1.1\n", 16);
598 //printf("TEST: '%s'\n",input.content());
599 HttpParserInit(&output, input.content(), input.contentSize());
600 Config.onoff.relaxed_header_parser = 0;
601 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
602 CPPUNIT_ASSERT_EQUAL(HTTP_BAD_REQUEST, output.request_parse_status);
603 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
604 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
605 CPPUNIT_ASSERT(memcmp(" GET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
606 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
607 CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
608 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
609 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
610 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
611 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
612 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
613 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
614 input.reset();
615
616 // tab padded method (NP: tab is not SP so treated as any other binary)
617 input.append("\tGET / HTTP/1.1\n", 16);
618 //printf("TEST: '%s'\n",input.content());
619 HttpParserInit(&output, input.content(), input.contentSize());
620 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
621 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
622 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
623 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
624 CPPUNIT_ASSERT(memcmp("\tGET / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
625 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
626 CPPUNIT_ASSERT_EQUAL(3, output.m_end);
627 CPPUNIT_ASSERT(memcmp("\tGET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
628 CPPUNIT_ASSERT_EQUAL(5, output.u_start);
629 CPPUNIT_ASSERT_EQUAL(5, output.u_end);
630 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
631 CPPUNIT_ASSERT_EQUAL(7, output.v_start);
632 CPPUNIT_ASSERT_EQUAL(14, output.v_end);
633 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
634 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
635 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
636 input.reset();
637
638 input.append("GET", 3);
639 //printf("TEST: '%s'\n",input.content());
640 HttpParserInit(&output, input.content(), input.contentSize());
641 CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
642 CPPUNIT_ASSERT_EQUAL(HTTP_STATUS_NONE, output.request_parse_status);
643 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
644 CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
645 CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
646 CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
647 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
648 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
649 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
650 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
651 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
652 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
653 input.reset();
654
655 input.append("GET ", 4);
656 //printf("TEST: '%s'\n",input.content());
657 HttpParserInit(&output, input.content(), input.contentSize());
658 CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
659 CPPUNIT_ASSERT_EQUAL(HTTP_STATUS_NONE, output.request_parse_status);
660 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
661 CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
662 CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
663 CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
664 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
665 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
666 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
667 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
668 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
669 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
670 input.reset();
671
672 input.append("GET / HT", 8);
673 //printf("TEST: '%s'\n",input.content());
674 HttpParserInit(&output, input.content(), input.contentSize());
675 CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
676 CPPUNIT_ASSERT_EQUAL(HTTP_STATUS_NONE, output.request_parse_status);
677 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
678 CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
679 CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
680 CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
681 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
682 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
683 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
684 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
685 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
686 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
687 input.reset();
688
689 input.append("GET / HTTP/1.1", 14);
690 //printf("TEST: '%s'\n",input.content());
691 HttpParserInit(&output, input.content(), input.contentSize());
692 CPPUNIT_ASSERT_EQUAL(0, HttpParserParseReqLine(&output));
693 CPPUNIT_ASSERT_EQUAL(HTTP_STATUS_NONE, output.request_parse_status);
694 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
695 CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
696 CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
697 CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
698 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
699 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
700 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
701 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
702 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
703 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
704 input.reset();
705
706 // method-only
707 input.append("A\n", 2);
708 //printf("TEST: '%s'\n",input.content());
709 HttpParserInit(&output, input.content(), input.contentSize());
710 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
711 CPPUNIT_ASSERT_EQUAL(HTTP_BAD_REQUEST, output.request_parse_status);
712 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
713 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
714 CPPUNIT_ASSERT(memcmp("A\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
715 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
716 CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
717 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
718 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
719 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
720 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
721 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
722 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
723 input.reset();
724
725 // no method (but in a form which is ambiguous with HTTP/0.9 simple-request)
726 input.append("/ HTTP/1.0\n", 11);
727 //printf("TEST: '%s'\n",input.content());
728 HttpParserInit(&output, input.content(), input.contentSize());
729 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
730 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
731 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
732 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
733 CPPUNIT_ASSERT(memcmp("/ HTTP/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
734 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
735 CPPUNIT_ASSERT_EQUAL(0, output.m_end);
736 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
737 CPPUNIT_ASSERT_EQUAL(2, output.u_start);
738 CPPUNIT_ASSERT_EQUAL(9, output.u_end);
739 CPPUNIT_ASSERT(memcmp("HTTP/1.0", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
740 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
741 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
742 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
743 CPPUNIT_ASSERT_EQUAL(9, output.v_min);
744 input.reset();
745
746 // RELAXED no method (an invalid format)
747 input.append(" / HTTP/1.0\n", 12);
748 //printf("TEST: '%s'\n",input.content());
749 HttpParserInit(&output, input.content(), input.contentSize());
750 // When tolerantly ignoring SP prefix this case becomes ambiguous with HTTP/0.9 simple-request)
751 Config.onoff.relaxed_header_parser = 1;
752 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
753 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
754 CPPUNIT_ASSERT_EQUAL(1, output.req_start);
755 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
756 CPPUNIT_ASSERT(memcmp("/ HTTP/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
757 CPPUNIT_ASSERT_EQUAL(1, output.m_start);
758 CPPUNIT_ASSERT_EQUAL(1, output.m_end);
759 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
760 CPPUNIT_ASSERT_EQUAL(3, output.u_start);
761 CPPUNIT_ASSERT_EQUAL(10, output.u_end);
762 CPPUNIT_ASSERT(memcmp("HTTP/1.0", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
763 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
764 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
765 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
766 CPPUNIT_ASSERT_EQUAL(9, output.v_min);
767 input.reset();
768
769 // STRICT no method (an invalid format)
770 input.append(" / HTTP/1.0\n", 12);
771 //printf("TEST: '%s'\n",input.content());
772 HttpParserInit(&output, input.content(), input.contentSize());
773 // When tolerantly ignoring SP prefix this case becomes ambiguous with HTTP/0.9 simple-request)
774 Config.onoff.relaxed_header_parser = 0;
775 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
776 CPPUNIT_ASSERT_EQUAL(HTTP_BAD_REQUEST, output.request_parse_status);
777 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
778 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
779 CPPUNIT_ASSERT(memcmp(" / HTTP/1.0\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
780 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
781 CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
782 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
783 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
784 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
785 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
786 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
787 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
788 input.reset();
789
790 // binary code in method (strange but ...)
791 input.append("GET\x0B / HTTP/1.1\n", 16);
792 //printf("TEST: %d-%d/%d '%.*s'\n", output.req_start, output.req_end, input.contentSize(), 16, input.content());
793 HttpParserInit(&output, input.content(), input.contentSize());
794 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
795 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
796 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
797 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
798 CPPUNIT_ASSERT(memcmp("GET\x0B / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
799 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
800 CPPUNIT_ASSERT_EQUAL(3, output.m_end);
801 CPPUNIT_ASSERT(memcmp("GET\x0B", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
802 CPPUNIT_ASSERT_EQUAL(5, output.u_start);
803 CPPUNIT_ASSERT_EQUAL(5, output.u_end);
804 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
805 CPPUNIT_ASSERT_EQUAL(7, output.v_start);
806 CPPUNIT_ASSERT_EQUAL(14, output.v_end);
807 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
808 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
809 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
810 input.reset();
811
812 // CR in method
813 // RFC 2616 sec 5.1 prohibits CR other than in terminator.
814 input.append("GET\r / HTTP/1.1\r\n", 16);
815 //printf("TEST: '%s'\n",input.content());
816 HttpParserInit(&output, input.content(), input.contentSize());
817 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
818 CPPUNIT_ASSERT_EQUAL(HTTP_BAD_REQUEST, output.request_parse_status);
819 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
820 CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
821 CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
822 CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
823 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
824 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
825 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
826 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
827 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
828 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
829 input.reset();
830
831 // binary code NUL! in method (strange but ...)
832 input.append("GET\0 / HTTP/1.1\n", 16);
833 //printf("TEST: %d-%d/%d '%.*s'\n", output.req_start, output.req_end, input.contentSize(), 16, input.content());
834 HttpParserInit(&output, input.content(), input.contentSize());
835 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
836 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
837 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
838 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
839 CPPUNIT_ASSERT(memcmp("GET\0 / HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
840 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
841 CPPUNIT_ASSERT_EQUAL(3, output.m_end);
842 CPPUNIT_ASSERT(memcmp("GET\0", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
843 CPPUNIT_ASSERT_EQUAL(5, output.u_start);
844 CPPUNIT_ASSERT_EQUAL(5, output.u_end);
845 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
846 CPPUNIT_ASSERT_EQUAL(7, output.v_start);
847 CPPUNIT_ASSERT_EQUAL(14, output.v_end);
848 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
849 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
850 CPPUNIT_ASSERT_EQUAL(1, output.v_min);
851 input.reset();
852
853 // no URL (grammer otherwise correct)
854 input.append("GET HTTP/1.1\n", 14);
855 //printf("TEST: '%s'\n",input.content());
856 HttpParserInit(&output, input.content(), input.contentSize());
857 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
858 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
859 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
860 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
861 CPPUNIT_ASSERT(memcmp("GET HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
862 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
863 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
864 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
865 CPPUNIT_ASSERT_EQUAL(5, output.u_start);
866 CPPUNIT_ASSERT_EQUAL(12, output.u_end);
867 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
868 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
869 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
870 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
871 CPPUNIT_ASSERT_EQUAL(9, output.v_min);
872 input.reset();
873
874 // no URL (grammer invalid, ambiguous with RFC 1945 HTTP/0.9 simple-request)
875 input.append("GET HTTP/1.1\n", 13);
876 //printf("TEST: '%s'\n",input.content());
877 HttpParserInit(&output, input.content(), input.contentSize());
878 CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
879 CPPUNIT_ASSERT_EQUAL(HTTP_OK, output.request_parse_status);
880 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
881 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
882 CPPUNIT_ASSERT(memcmp("GET HTTP/1.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
883 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
884 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
885 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
886 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
887 CPPUNIT_ASSERT_EQUAL(11, output.u_end);
888 CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
889 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
890 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
891 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
892 CPPUNIT_ASSERT_EQUAL(9, output.v_min);
893 input.reset();
894
895 // no version
896 input.append("GET / HTTP/\n", 12);
897 //printf("TEST: '%s'\n",input.content());
898 HttpParserInit(&output, input.content(), input.contentSize());
899 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
900 CPPUNIT_ASSERT_EQUAL(HTTP_HTTP_VERSION_NOT_SUPPORTED, output.request_parse_status);
901 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
902 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
903 CPPUNIT_ASSERT(memcmp("GET / HTTP/\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
904 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
905 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
906 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
907 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
908 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
909 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
910 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
911 CPPUNIT_ASSERT_EQUAL(10, output.v_end);
912 CPPUNIT_ASSERT(memcmp("HTTP/", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
913 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
914 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
915 input.reset();
916
917 // no major version
918 input.append("GET / HTTP/.1\n", 14);
919 //printf("TEST: '%s'\n",input.content());
920 HttpParserInit(&output, input.content(), input.contentSize());
921 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
922 CPPUNIT_ASSERT_EQUAL(HTTP_HTTP_VERSION_NOT_SUPPORTED, output.request_parse_status);
923 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
924 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
925 CPPUNIT_ASSERT(memcmp("GET / HTTP/.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
926 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
927 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
928 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
929 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
930 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
931 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
932 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
933 CPPUNIT_ASSERT_EQUAL(12, output.v_end);
934 CPPUNIT_ASSERT(memcmp("HTTP/.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
935 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
936 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
937 input.reset();
938
939 // no version dot
940 input.append("GET / HTTP/11\n", 14);
941 //printf("TEST: '%s'\n",input.content());
942 HttpParserInit(&output, input.content(), input.contentSize());
943 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
944 CPPUNIT_ASSERT_EQUAL(HTTP_HTTP_VERSION_NOT_SUPPORTED, output.request_parse_status);
945 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
946 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
947 CPPUNIT_ASSERT(memcmp("GET / HTTP/11\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
948 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
949 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
950 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
951 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
952 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
953 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
954 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
955 CPPUNIT_ASSERT_EQUAL(12, output.v_end);
956 CPPUNIT_ASSERT(memcmp("HTTP/11", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
957 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
958 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
959 input.reset();
960
961 // negative major version (bug 3062)
962 input.append("GET / HTTP/-999999.1\n", 21);
963 //printf("TEST: '%s'\n",input.content());
964 HttpParserInit(&output, input.content(), input.contentSize());
965 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
966 CPPUNIT_ASSERT_EQUAL(HTTP_HTTP_VERSION_NOT_SUPPORTED, output.request_parse_status);
967 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
968 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
969 CPPUNIT_ASSERT(memcmp("GET / HTTP/-999999.1\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
970 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
971 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
972 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
973 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
974 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
975 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
976 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
977 CPPUNIT_ASSERT_EQUAL(19, output.v_end);
978 CPPUNIT_ASSERT(memcmp("HTTP/-999999.1", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
979 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
980 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
981 input.reset();
982
983 // no minor version
984 input.append("GET / HTTP/1.\n", 14);
985 //printf("TEST: '%s'\n",input.content());
986 HttpParserInit(&output, input.content(), input.contentSize());
987 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
988 CPPUNIT_ASSERT_EQUAL(HTTP_HTTP_VERSION_NOT_SUPPORTED, output.request_parse_status);
989 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
990 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
991 CPPUNIT_ASSERT(memcmp("GET / HTTP/1.\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
992 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
993 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
994 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
995 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
996 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
997 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
998 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
999 CPPUNIT_ASSERT_EQUAL(12, output.v_end);
1000 CPPUNIT_ASSERT(memcmp("HTTP/1.", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
1001 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
1002 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
1003 input.reset();
1004
1005 // negative major version (bug 3062 corollary)
1006 input.append("GET / HTTP/1.-999999\n", 21);
1007 //printf("TEST: '%s'\n",input.content());
1008 HttpParserInit(&output, input.content(), input.contentSize());
1009 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
1010 CPPUNIT_ASSERT_EQUAL(HTTP_HTTP_VERSION_NOT_SUPPORTED, output.request_parse_status);
1011 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
1012 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
1013 CPPUNIT_ASSERT(memcmp("GET / HTTP/1.-999999\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
1014 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
1015 CPPUNIT_ASSERT_EQUAL(2, output.m_end);
1016 CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
1017 CPPUNIT_ASSERT_EQUAL(4, output.u_start);
1018 CPPUNIT_ASSERT_EQUAL(4, output.u_end);
1019 CPPUNIT_ASSERT(memcmp("/", &output.buf[output.u_start],(output.u_end-output.u_start+1)) == 0);
1020 CPPUNIT_ASSERT_EQUAL(6, output.v_start);
1021 CPPUNIT_ASSERT_EQUAL(19, output.v_end);
1022 CPPUNIT_ASSERT(memcmp("HTTP/1.-999999", &output.buf[output.v_start],(output.v_end-output.v_start+1)) == 0);
1023 CPPUNIT_ASSERT_EQUAL(1, output.v_maj);
1024 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
1025 input.reset();
1026
1027 // binary line
1028 input.append("\xB\xC\xE\xF\n", 5);
1029 //printf("TEST: binary-line\n");
1030 HttpParserInit(&output, input.content(), input.contentSize());
1031 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
1032 CPPUNIT_ASSERT_EQUAL(HTTP_BAD_REQUEST, output.request_parse_status);
1033 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
1034 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
1035 CPPUNIT_ASSERT(memcmp("\xB\xC\xE\xF\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
1036 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
1037 CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
1038 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
1039 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
1040 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
1041 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
1042 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
1043 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
1044 input.reset();
1045
1046 // mixed whitespace line
1047 // We accept non-space binary bytes for method so first \t shows up as that
1048 // but remaining space and tabs are skipped searching for URI-start
1049 input.append("\t \t \t\n", 6);
1050 //printf("TEST: mixed whitespace\n");
1051 HttpParserInit(&output, input.content(), input.contentSize());
1052 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
1053 CPPUNIT_ASSERT_EQUAL(HTTP_BAD_REQUEST, output.request_parse_status);
1054 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
1055 CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req_end);
1056 CPPUNIT_ASSERT(memcmp("\t \t \t\n", &output.buf[output.req_start],(output.req_end-output.req_start+1)) == 0);
1057 CPPUNIT_ASSERT_EQUAL(0, output.m_start);
1058 CPPUNIT_ASSERT_EQUAL(0, output.m_end);
1059 CPPUNIT_ASSERT(memcmp("\t", &output.buf[output.m_start],(output.m_end-output.m_start+1)) == 0);
1060 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
1061 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
1062 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
1063 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
1064 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
1065 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
1066 input.reset();
1067
1068 // mixed whitespace line with CR middle
1069 // CR aborts on sight, so even initial \t method is not marked as above
1070 // (not when parsing clean with whole line available anyway)
1071 input.append("\t \r \n", 6);
1072 //printf("TEST: mixed whitespace with CR\n");
1073 HttpParserInit(&output, input.content(), input.contentSize());
1074 CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
1075 CPPUNIT_ASSERT_EQUAL(HTTP_BAD_REQUEST, output.request_parse_status);
1076 CPPUNIT_ASSERT_EQUAL(0, output.req_start);
1077 CPPUNIT_ASSERT_EQUAL(-1, output.req_end);
1078 CPPUNIT_ASSERT_EQUAL(-1, output.m_start);
1079 CPPUNIT_ASSERT_EQUAL(-1, output.m_end);
1080 CPPUNIT_ASSERT_EQUAL(-1, output.u_start);
1081 CPPUNIT_ASSERT_EQUAL(-1, output.u_end);
1082 CPPUNIT_ASSERT_EQUAL(-1, output.v_start);
1083 CPPUNIT_ASSERT_EQUAL(-1, output.v_end);
1084 CPPUNIT_ASSERT_EQUAL(0, output.v_maj);
1085 CPPUNIT_ASSERT_EQUAL(0, output.v_min);
1086 input.reset();
1087 }