input.init();
// no method (but in a form which is ambiguous with HTTP/0.9 simple-request)
- // XXX: Bug: HTTP/0.9 requires method to be "GET"
- input.append("/ HTTP/1.0\n", 11);
- //printf("TEST: '%s'\n",input.content());
- output.reset(input.content(), input.contentSize());
- CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
- CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
- CPPUNIT_ASSERT_EQUAL(0, output.req.start);
- CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
- CPPUNIT_ASSERT(memcmp("/ HTTP/1.0\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
- CPPUNIT_ASSERT_EQUAL(0, output.req.m_end);
- CPPUNIT_ASSERT(memcmp("/", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(2, output.req.u_start);
- CPPUNIT_ASSERT_EQUAL(9, output.req.u_end);
- CPPUNIT_ASSERT(memcmp("HTTP/1.0", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
- CPPUNIT_ASSERT_EQUAL(9, output.req.v_min);
- input.reset();
+ {
+ // XXX: Bug: HTTP/0.9 requires method to be "GET"
+ input.append("/ HTTP/1.0\n", 11);
+ //printf("TEST: '%s'\n",input.content());
+ output.reset(input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("/ HTTP/1.0\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)));
+ CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.m_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)));
+ CPPUNIT_ASSERT_EQUAL(2, output.req.u_start);
+ CPPUNIT_ASSERT_EQUAL(9, output.req.u_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("HTTP/1.0", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)));
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
+ CPPUNIT_ASSERT_EQUAL(9, output.req.v_min);
+ input.reset();
+ }
// RELAXED no method (an invalid format)
- input.append(" / HTTP/1.0\n", 12);
- //printf("TEST: '%s'\n",input.content());
- output.reset(input.content(), input.contentSize());
- // When tolerantly ignoring SP prefix this case becomes ambiguous with HTTP/0.9 simple-request)
- Config.onoff.relaxed_header_parser = 1;
- CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
- CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
- CPPUNIT_ASSERT_EQUAL(1, output.req.start);
- CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
- CPPUNIT_ASSERT(memcmp("/ HTTP/1.0\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(1, output.req.m_start);
- CPPUNIT_ASSERT_EQUAL(1, output.req.m_end);
- CPPUNIT_ASSERT(memcmp("/", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(3, output.req.u_start);
- CPPUNIT_ASSERT_EQUAL(10, output.req.u_end);
- CPPUNIT_ASSERT(memcmp("HTTP/1.0", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
- CPPUNIT_ASSERT_EQUAL(9, output.req.v_min);
- input.reset();
+ {
+ input.append(" / HTTP/1.0\n", 12);
+ //printf("TEST: '%s'\n",input.content());
+ output.reset(input.content(), input.contentSize());
+ // When tolerantly ignoring SP prefix this case becomes ambiguous with HTTP/0.9 simple-request)
+ Config.onoff.relaxed_header_parser = 1;
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
+ CPPUNIT_ASSERT_EQUAL(1, output.req.start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("/ HTTP/1.0\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)));
+ CPPUNIT_ASSERT_EQUAL(1, output.req.m_start);
+ CPPUNIT_ASSERT_EQUAL(1, output.req.m_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)));
+ CPPUNIT_ASSERT_EQUAL(3, output.req.u_start);
+ CPPUNIT_ASSERT_EQUAL(10, output.req.u_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("HTTP/1.0", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)));
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
+ CPPUNIT_ASSERT_EQUAL(9, output.req.v_min);
+ input.reset();
+ }
// STRICT no method (an invalid format)
- input.append(" / HTTP/1.0\n", 12);
- //printf("TEST: '%s'\n",input.content());
- output.reset(input.content(), input.contentSize());
- // When tolerantly ignoring SP prefix this case becomes ambiguous with HTTP/0.9 simple-request)
- Config.onoff.relaxed_header_parser = 0;
- CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
- CPPUNIT_ASSERT_EQUAL(Http::scBadRequest, output.request_parse_status);
- CPPUNIT_ASSERT_EQUAL(0, output.req.start);
- CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
- CPPUNIT_ASSERT(memcmp(" / HTTP/1.0\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_min);
- input.reset();
+ {
+ input.append(" / HTTP/1.0\n", 12);
+ //printf("TEST: '%s'\n",input.content());
+ output.reset(input.content(), input.contentSize());
+ // When tolerantly ignoring SP prefix this case becomes ambiguous with HTTP/0.9 simple-request)
+ Config.onoff.relaxed_header_parser = 0;
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(Http::scBadRequest, output.request_parse_status);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp(" / HTTP/1.0\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)));
+ CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_min);
+ input.reset();
+ }
// binary code in method (strange but ...)
- input.append("GET\x0B / HTTP/1.1\n", 16);
- //printf("TEST: %d-%d/%d '%.*s'\n", output.req.start, output.req.end, input.contentSize(), 16, input.content());
- output.reset(input.content(), input.contentSize());
- CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
- CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
- CPPUNIT_ASSERT_EQUAL(0, output.req.start);
- CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
- CPPUNIT_ASSERT(memcmp("GET\x0B / HTTP/1.1\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
- CPPUNIT_ASSERT_EQUAL(3, output.req.m_end);
- CPPUNIT_ASSERT(memcmp("GET\x0B", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(5, output.req.u_start);
- CPPUNIT_ASSERT_EQUAL(5, output.req.u_end);
- CPPUNIT_ASSERT(memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(7, output.req.v_start);
- CPPUNIT_ASSERT_EQUAL(14, output.req.v_end);
- CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.req.v_start],(output.req.v_end-output.req.v_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(1, output.req.v_maj);
- CPPUNIT_ASSERT_EQUAL(1, output.req.v_min);
- input.reset();
+ {
+ input.append("GET\x0B / HTTP/1.1\n", 16);
+ //printf("TEST: %d-%d/%d '%.*s'\n", output.req.start, output.req.end, input.contentSize(), 16, input.content());
+ output.reset(input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("GET\x0B / HTTP/1.1\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)));
+ CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
+ CPPUNIT_ASSERT_EQUAL(3, output.req.m_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("GET\x0B", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)));
+ CPPUNIT_ASSERT_EQUAL(5, output.req.u_start);
+ CPPUNIT_ASSERT_EQUAL(5, output.req.u_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)));
+ CPPUNIT_ASSERT_EQUAL(7, output.req.v_start);
+ CPPUNIT_ASSERT_EQUAL(14, output.req.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("HTTP/1.1", &output.buf[output.req.v_start],(output.req.v_end-output.req.v_start+1)));
+ CPPUNIT_ASSERT_EQUAL(1, output.req.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.req.v_min);
+ input.reset();
+ }
// CR in method
- // RFC 2616 sec 5.1 prohibits CR other than in terminator.
- input.append("GET\r / HTTP/1.1\r\n", 16);
- //printf("TEST: '%s'\n",input.content());
- output.reset(input.content(), input.contentSize());
- CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
- CPPUNIT_ASSERT_EQUAL(Http::scBadRequest, output.request_parse_status);
- CPPUNIT_ASSERT_EQUAL(0, output.req.start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.m_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_min);
- input.reset();
+ {
+ // RFC 2616 sec 5.1 prohibits CR other than in terminator.
+ input.append("GET\r / HTTP/1.1\r\n", 16);
+ //printf("TEST: '%s'\n",input.content());
+ output.reset(input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(Http::scBadRequest, output.request_parse_status);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_min);
+ input.reset();
+ }
// binary code NUL! in method (strange but ...)
- input.append("GET\0 / HTTP/1.1\n", 16);
- //printf("TEST: %d-%d/%d '%.*s'\n", output.req.start, output.req.end, input.contentSize(), 16, input.content());
- output.reset(input.content(), input.contentSize());
- CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
- CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
- CPPUNIT_ASSERT_EQUAL(0, output.req.start);
- CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
- CPPUNIT_ASSERT(memcmp("GET\0 / HTTP/1.1\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
- CPPUNIT_ASSERT_EQUAL(3, output.req.m_end);
- CPPUNIT_ASSERT(memcmp("GET\0", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(5, output.req.u_start);
- CPPUNIT_ASSERT_EQUAL(5, output.req.u_end);
- CPPUNIT_ASSERT(memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(7, output.req.v_start);
- CPPUNIT_ASSERT_EQUAL(14, output.req.v_end);
- CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.req.v_start],(output.req.v_end-output.req.v_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(1, output.req.v_maj);
- CPPUNIT_ASSERT_EQUAL(1, output.req.v_min);
- input.reset();
+ {
+ input.append("GET\0 / HTTP/1.1\n", 16);
+ //printf("TEST: %d-%d/%d '%.*s'\n", output.req.start, output.req.end, input.contentSize(), 16, input.content());
+ output.reset(input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("GET\0 / HTTP/1.1\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)));
+ CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
+ CPPUNIT_ASSERT_EQUAL(3, output.req.m_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("GET\0", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)));
+ CPPUNIT_ASSERT_EQUAL(5, output.req.u_start);
+ CPPUNIT_ASSERT_EQUAL(5, output.req.u_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("/", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)));
+ CPPUNIT_ASSERT_EQUAL(7, output.req.v_start);
+ CPPUNIT_ASSERT_EQUAL(14, output.req.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("HTTP/1.1", &output.buf[output.req.v_start],(output.req.v_end-output.req.v_start+1)));
+ CPPUNIT_ASSERT_EQUAL(1, output.req.v_maj);
+ CPPUNIT_ASSERT_EQUAL(1, output.req.v_min);
+ input.reset();
+ }
// no URL (grammer otherwise correct)
- input.append("GET HTTP/1.1\n", 14);
- //printf("TEST: '%s'\n",input.content());
- output.reset(input.content(), input.contentSize());
- CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
- CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
- CPPUNIT_ASSERT_EQUAL(0, output.req.start);
- CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
- CPPUNIT_ASSERT(memcmp("GET HTTP/1.1\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
- CPPUNIT_ASSERT_EQUAL(2, output.req.m_end);
- CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(5, output.req.u_start);
- CPPUNIT_ASSERT_EQUAL(12, output.req.u_end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
- CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
- CPPUNIT_ASSERT_EQUAL(9, output.req.v_min);
- input.reset();
+ {
+ input.append("GET HTTP/1.1\n", 14);
+ //printf("TEST: '%s'\n",input.content());
+ output.reset(input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("GET HTTP/1.1\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)));
+ CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.req.m_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)));
+ CPPUNIT_ASSERT_EQUAL(5, output.req.u_start);
+ CPPUNIT_ASSERT_EQUAL(12, output.req.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("HTTP/1.1", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)));
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
+ CPPUNIT_ASSERT_EQUAL(9, output.req.v_min);
+ input.reset();
+ }
// no URL (grammer invalid, ambiguous with RFC 1945 HTTP/0.9 simple-request)
- input.append("GET HTTP/1.1\n", 13);
- //printf("TEST: '%s'\n",input.content());
- output.reset(input.content(), input.contentSize());
- CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
- CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
- CPPUNIT_ASSERT_EQUAL(0, output.req.start);
- CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
- CPPUNIT_ASSERT(memcmp("GET HTTP/1.1\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
- CPPUNIT_ASSERT_EQUAL(2, output.req.m_end);
- CPPUNIT_ASSERT(memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(4, output.req.u_start);
- CPPUNIT_ASSERT_EQUAL(11, output.req.u_end);
- CPPUNIT_ASSERT(memcmp("HTTP/1.1", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
- CPPUNIT_ASSERT_EQUAL(9, output.req.v_min);
- input.reset();
+ {
+ input.append("GET HTTP/1.1\n", 13);
+ //printf("TEST: '%s'\n",input.content());
+ output.reset(input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(Http::scOkay, output.request_parse_status);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("GET HTTP/1.1\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)));
+ CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
+ CPPUNIT_ASSERT_EQUAL(2, output.req.m_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("GET", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)));
+ CPPUNIT_ASSERT_EQUAL(4, output.req.u_start);
+ CPPUNIT_ASSERT_EQUAL(11, output.req.u_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("HTTP/1.1", &output.buf[output.req.u_start],(output.req.u_end-output.req.u_start+1)));
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
+ CPPUNIT_ASSERT_EQUAL(9, output.req.v_min);
+ input.reset();
+ }
// binary line
- input.append("\xB\xC\xE\xF\n", 5);
- //printf("TEST: binary-line\n");
- output.reset(input.content(), input.contentSize());
- CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
- CPPUNIT_ASSERT_EQUAL(Http::scBadRequest, output.request_parse_status);
- CPPUNIT_ASSERT_EQUAL(0, output.req.start);
- CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
- CPPUNIT_ASSERT(memcmp("\xB\xC\xE\xF\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_min);
- input.reset();
+ {
+ input.append("\xB\xC\xE\xF\n", 5);
+ //printf("TEST: binary-line\n");
+ output.reset(input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(Http::scBadRequest, output.request_parse_status);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("\xB\xC\xE\xF\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)));
+ CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_min);
+ input.reset();
+ }
// mixed whitespace line
- // We accept non-space binary bytes for method so first \t shows up as that
- // but remaining space and tabs are skipped searching for URI-start
- input.append("\t \t \t\n", 6);
- //printf("TEST: mixed whitespace\n");
- output.reset(input.content(), input.contentSize());
- CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
- CPPUNIT_ASSERT_EQUAL(Http::scBadRequest, output.request_parse_status);
- CPPUNIT_ASSERT_EQUAL(0, output.req.start);
- CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
- CPPUNIT_ASSERT(memcmp("\t \t \t\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
- CPPUNIT_ASSERT_EQUAL(0, output.req.m_end);
- CPPUNIT_ASSERT(memcmp("\t", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)) == 0);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_min);
- input.reset();
+ {
+ // We accept non-space binary bytes for method so first \t shows up as that
+ // but remaining space and tabs are skipped searching for URI-start
+ input.append("\t \t \t\n", 6);
+ //printf("TEST: mixed whitespace\n");
+ output.reset(input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(Http::scBadRequest, output.request_parse_status);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.start);
+ CPPUNIT_ASSERT_EQUAL((int)input.contentSize()-1, output.req.end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("\t \t \t\n", &output.buf[output.req.start],(output.req.end-output.req.start+1)));
+ CPPUNIT_ASSERT_EQUAL(0, output.req.m_start);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.m_end);
+ CPPUNIT_ASSERT_EQUAL(0, memcmp("\t", &output.buf[output.req.m_start],(output.req.m_end-output.req.m_start+1)));
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_min);
+ input.reset();
+ }
// mixed whitespace line with CR middle
- // CR aborts on sight, so even initial \t method is not marked as above
- // (not when parsing clean with whole line available anyway)
- input.append("\t \r \n", 6);
- //printf("TEST: mixed whitespace with CR\n");
- output.reset(input.content(), input.contentSize());
- CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
- CPPUNIT_ASSERT_EQUAL(Http::scBadRequest, output.request_parse_status);
- CPPUNIT_ASSERT_EQUAL(0, output.req.start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.m_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
- CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
- CPPUNIT_ASSERT_EQUAL(0, output.req.v_min);
- input.reset();
+ {
+ // CR aborts on sight, so even initial \t method is not marked as above
+ // (not when parsing clean with whole line available anyway)
+ input.append("\t \r \n", 6);
+ //printf("TEST: mixed whitespace with CR\n");
+ output.reset(input.content(), input.contentSize());
+ CPPUNIT_ASSERT_EQUAL(-1, HttpParserParseReqLine(&output));
+ CPPUNIT_ASSERT_EQUAL(Http::scBadRequest, output.request_parse_status);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.m_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.m_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.u_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.u_end);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_start);
+ CPPUNIT_ASSERT_EQUAL(-1, output.req.v_end);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_maj);
+ CPPUNIT_ASSERT_EQUAL(0, output.req.v_min);
+ input.reset();
+ }
}
+
+void
+testHttpParser::testDripFeed()
+{
+ // Simulate a client drip-feeding Squid a few bytes at a time.
+ // extend the size of the buffer from 0 bytes to full request length
+ // calling the parser repeatedly as visible data grows.
+
+ MemBuf mb;
+ mb.init(1024, 1024);
+ mb.append(" ", 12);
+ int garbageEnd = mb.contentSize();
+ mb.append("GET http://example.com/ HTTP/1.1\r\n", 34);
+ int reqLineEnd = mb.contentSize();
+ mb.append("\n", 1);
+
+ HttpParser hp(mb.content(), 0);
+
+ // only relaxed parser accepts the garbage whitespace
+ Config.onoff.relaxed_header_parser = 1;
+
+ for (; hp.bufsiz < mb.contentSize(); ++hp.bufsiz) {
+ int parseResult = hp.parseRequestFirstLine();
+
+#if WHEN_TEST_DEBUG_IS_NEEDED
+ printf("%d/%d :: %d, %d, %d '%c'\n", hp.bufsiz, mb.contentSize(),
+ garbageEnd, reqLineEnd, parseResult,
+ mb.content()[hp.bufsiz]);
+#endif
+
+ // before end of garbage found its a moving offset.
+ if (hp.bufsiz < garbageEnd) {
+ CPPUNIT_ASSERT_EQUAL(hp.bufsiz, (int)hp.parseOffset_);
+ continue;
+ }
+
+ // before request line found, parse announces incomplete
+ if (hp.bufsiz < reqLineEnd) {
+ CPPUNIT_ASSERT_EQUAL(garbageEnd, (int)hp.parseOffset_);
+ CPPUNIT_ASSERT_EQUAL(0, parseResult);
+ continue;
+ }
+
+ // once request line is found (AND the following \n) current parser announces success
+ CPPUNIT_ASSERT_EQUAL(reqLineEnd, (int)hp.parseOffset_);
+ CPPUNIT_ASSERT_EQUAL(1, parseResult);
+ }
+}