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