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