1 #define SQUID_UNIT_TEST 1
4 #include <cppunit/TestAssert.h>
6 #include "testHttpRequest.h"
7 #include "HttpRequest.h"
11 CPPUNIT_TEST_SUITE_REGISTRATION( testHttpRequest
);
13 /** wrapper for testing HttpRequest object private and protected functions */
14 class PrivateHttpRequest
: public HttpRequest
17 bool doSanityCheckStartLine(MemBuf
*b
, const size_t h
, http_status
*e
) { return sanityCheckStartLine(b
,h
,e
); };
20 /* init memory pools */
23 testHttpRequest::setUp()
26 httpHeaderInitModule();
30 * Test creating an HttpRequest object from a Url and method
33 testHttpRequest::testCreateFromUrlAndMethod()
37 char * url
= xstrdup("http://foo:90/bar");
38 HttpRequest
*aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, METHOD_GET
);
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(AnyP::PROTO_HTTP
, aRequest
->protocol
);
46 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url
));
49 /* vanilla url, different method */
50 url
= xstrdup("http://foo/bar");
51 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, METHOD_PUT
);
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(AnyP::PROTO_HTTP
, aRequest
->protocol
);
58 CPPUNIT_ASSERT_EQUAL(String("http://foo/bar"), String(url
));
60 /* a connect url with non-CONNECT data */
61 url
= xstrdup(":foo/bar");
62 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, METHOD_CONNECT
);
64 CPPUNIT_ASSERT_EQUAL(nullRequest
, aRequest
);
66 /* a CONNECT url with CONNECT data */
67 url
= xstrdup("foo:45");
68 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, METHOD_CONNECT
);
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(AnyP::PROTO_NONE
, aRequest
->protocol
);
75 CPPUNIT_ASSERT_EQUAL(String("foo:45"), String(url
));
80 * Test creating an HttpRequest object from a Url alone.
83 testHttpRequest::testCreateFromUrl()
87 char * url
= xstrdup("http://foo:90/bar");
88 HttpRequest
*aRequest
= HttpRequest::CreateFromUrl(url
);
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(AnyP::PROTO_HTTP
, aRequest
->protocol
);
95 CPPUNIT_ASSERT_EQUAL(String("http://foo:90/bar"), String(url
));
100 * Test BUG: URL '2000:800:45' opens host 2000 port 800 !!
103 testHttpRequest::testIPv6HostColonBug()
105 ushort expected_port
;
107 HttpRequest
*aRequest
= NULL
;
109 /* valid IPv6 address without port */
110 url
= xstrdup("http://[2000:800::45]/foo");
111 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, METHOD_GET
);
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(AnyP::PROTO_HTTP
, aRequest
->protocol
);
118 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]/foo"), String(url
));
121 /* valid IPv6 address with port */
122 url
= xstrdup("http://[2000:800::45]:90/foo");
123 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, METHOD_GET
);
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(AnyP::PROTO_HTTP
, aRequest
->protocol
);
130 CPPUNIT_ASSERT_EQUAL(String("http://[2000:800::45]:90/foo"), String(url
));
133 /* IPv6 address as invalid (bug trigger) */
134 url
= xstrdup("http://2000:800::45/foo");
135 aRequest
= HttpRequest::CreateFromUrlAndMethod(url
, METHOD_GET
);
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(AnyP::PROTO_HTTP
, aRequest
->protocol
);
142 CPPUNIT_ASSERT_EQUAL(String("http://2000:800::45/foo"), String(url
));
147 testHttpRequest::testSanityCheckStartLine()
150 PrivateHttpRequest engine
;
151 http_status error
= HTTP_STATUS_NONE
;
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
);
161 error
= HTTP_STATUS_NONE
;
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
);
168 error
= HTTP_STATUS_NONE
;
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
);
176 error
= HTTP_STATUS_NONE
;
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
);
183 error
= HTTP_STATUS_NONE
;
187 // TODO binary code in method
191 // TODO no status (okay)
193 // TODO non-HTTP protocol
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
);
200 error
= HTTP_STATUS_NONE
;
204 testHttpRequest::testParseRequestLine()
210 // TEST: Do we comply with RFC 1945 section 5.1 ?
211 // TEST: Do we comply with RFC 2616 section 5.1 ?
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);