11#include <cppunit/TestAssert.h>
14#define protected public
57 static bool setup_done =
false;
82#ifdef SQUID_DEBUG_TESTS
103 Replace(raw,
SBuf(
"\r"),
SBuf(
"\\r"));
104 Replace(raw,
SBuf(
"\n"),
SBuf(
"\\n"));
112#ifdef SQUID_DEBUG_TESTS
113 std::cerr <<
"TEST @" << line <<
", in=" << Pretty(input) <<
"\n";
118 const bool parsed = output.
parse(input);
120#ifdef SQUID_DEBUG_TESTS
121 if (expect.
parsed != parsed)
122 std::cerr <<
"\tparse-FAILED: " << expect.
parsed <<
"!=" << parsed <<
"\n";
124 std::cerr <<
"\tmethod-FAILED: " << expect.
method <<
"!=" << output.
method_ <<
"\n";
128 std::cerr <<
"\tsuffixSz-FAILED: " << expect.
suffixSz <<
"!=" << output.
buf_.
length() <<
"\n";
132 CPPUNIT_ASSERT_EQUAL(expect.
parsed, parsed);
137 if (expect.
uri !=
nullptr)
138 CPPUNIT_ASSERT_EQUAL(0, output.
uri_.
cmp(expect.
uri));
194 input.
append(
"GET /\r\n", 7);
212 input.
append(
"POST /\r\n", 8);
218 .suffixSz = input.
length(),
230 input.
append(
"GET / HTTP/1.0\r\n", 16);
248 input.
append(
"GET / HTTP/1.1\r\n", 16);
266 input.
append(
"GET / HTTP/1.2\r\n", 16);
286 input.
append(
"GET / HTTP/2.0\r\n", 16);
301 input.
append(
"GET / HTTP/9.9\r\n", 16);
319 input.
append(
"GET / HTTP/10.12\r\n", 18);
325 .suffixSz = input.
length(),
337 input.
append(
"GET / FOO/1.0\r\n", 15);
343 .suffixSz = input.
length(),
355 input.
append(
"GET / HTTP/\r\n", 13);
361 .suffixSz = input.
length(),
373 input.
append(
"GET / HTTP/.1\r\n", 15);
379 .suffixSz = input.
length(),
391 input.
append(
"GET / HTTP/11\r\n", 15);
397 .suffixSz = input.
length(),
409 input.
append(
"GET / HTTP/-999999.1\r\n", 22);
415 .suffixSz = input.
length(),
427 input.
append(
"GET / HTTP/1.\r\n", 15);
433 .suffixSz = input.
length(),
445 input.
append(
"GET / HTTP/1.-999999\r\n", 22);
451 .suffixSz = input.
length(),
473 input.
append(
"GET / HTTP/1.1\r\n", 21);
495 .suffixSz = input.
length(),
501 testResults(__LINE__, input, output, expectStrict);
507 input.
append(
"GET /fo o/ HTTP/1.1\r\n", 21);
528 .suffixSz = input.
length(),
534 testResults(__LINE__, input, output, expectStrict);
540 input.
append(
"GET / HTTP/1.1\r\nboo!", 20);
570 input.
append(
"GET / HTTP/1.1\n", 15);
591 .suffixSz = input.
length(),
597 testResults(__LINE__, input, output, expectStrict);
605 input.
append(
"GET / HTTP/1.1\n\n", 16);
626 .suffixSz = input.
length(),
632 testResults(__LINE__, input, output, expectStrict);
639 input.
append(
"GET / HTTP/1.1 \r\n", 17);
645 .suffixSz = input.
length(),
667 input.
append(
". / HTTP/1.1\r\n", 14);
685 input.
append(
"!#$%&'*+-.^_`|~ / HTTP/1.1\r\n", 28);
703 input.
append(
"OPTIONS * HTTP/1.1\r\n", 20);
721 input.
append(
"HELLOWORLD / HTTP/1.1\r\n", 23);
745 .suffixSz = input.
length(),
762 .suffixSz = input.
length(),
774 input.
append(
" GET / HTTP/1.1\r\n", 17);
780 .suffixSz = input.
length(),
792 input.
append(
"\r\n\r\n\nGET / HTTP/1.1\r\n", 21);
813 .suffixSz = input.
length(),
819 testResults(__LINE__, input, output, expectStrict);
825 input.
append(
"\tGET / HTTP/1.1\r\n", 17);
831 .suffixSz = input.
length(),
844 input.
append(
"GET\r / HTTP/1.1\r\n", 17);
865 .suffixSz = input.
length(),
871 testResults(__LINE__, input, output, expectStrict);
878 input.
append(
"GET\r\t\x0B\x0C / HTTP/1.1\r\n", 20);
899 .suffixSz = input.
length(),
905 testResults(__LINE__, input, output, expectStrict);
922 input.
append(
"/ HTTP/1.0\n", 11);
928 .suffixSz = input.
length(),
940 input.
append(
" / HTTP/1.0\n", 12);
946 .suffixSz = input.
length(),
952 testResults(__LINE__, input, output, expectStrict);
958 input.
append(
"GET\x16 / HTTP/1.1\r\n", 17);
964 .suffixSz = input.
length(),
976 input.
append(
"GET\0 / HTTP/1.1\r\n", 17);
982 .suffixSz = input.
length(),
995 input.
append(
"GET HTTP/1.1\r\n", 15);
1002 .suffixSz = input.
length(),
1016 .suffixSz = input.
length(),
1022 testResults(__LINE__, input, output, expectStrict);
1029 input.
append(
"GET HTTP/1.1\r\n", 14);
1035 .suffixSz = input.
length(),
1047 input.
append(
"\xB\xC\xE\xF\n", 5);
1053 .suffixSz = input.
length(),
1065 input.
append(
"\t \t \t\n", 6);
1071 .suffixSz = input.
length(),
1083 input.
append(
"\r \t \n", 6);
1089 .suffixSz = input.
length(),
1108 data.
append(
"\n\n\n\n\n\n\n\n\n\n\n\n", 12);
1111 data.
append(
"http://example.com/ ", 20);
1112 data.
append(
"HTTP/1.1\r\n", 10);
1114 data.
append(
"Host: example.com\r\n\r\n", 21);
1157 if (pos == garbageEnd)
1161 if (pos >= garbageEnd)
1166 if (pos == reqLineEnd) {
1171 expect.
uri =
"http://example.com/";
1177 if (pos == mimeEnd) {
Http::StatusCode parseStatusCode
AnyP::ProtocolVersion msgProtocol_
what protocol label has been found in the first line (if any)
SBuf buf_
bytes remaining to be parsed
const SBuf & remaining() const
the remaining unprocessed section of buffer
ParseState parsingStage_
what stage the parser is currently up to
bool needsMoreData() const
bool parse(const SBuf &aBuf) override
HttpRequestMethod method_
what request method has been found on the first line
SBuf uri_
raw copy of the original client request-line URI field
static const size_type npos
size_type length() const
Returns the number of bytes stored in SBuf.
int cmp(const SBuf &S, const size_type n) const
shorthand version for compare()
size_type find(char c, size_type startPos=0) const
SBuf & append(const SBuf &S)
SBuf substr(size_type pos, size_type n=npos) const
MemBlob::size_type size_type
struct SquidConfig::@106 onoff
size_t maxRequestHeaderSize
int relaxed_header_parser
CPPUNIT_TEST(testParseRequestLineProtocols)
CPPUNIT_TEST(testParseRequestLineTerminators)
void testParseRequestLineStrange()
void testParseRequestLineInvalid()
CPPUNIT_TEST(testParseRequestLineStrange)
CPPUNIT_TEST(testParseRequestLineMethods)
CPPUNIT_TEST(testParseRequestLineInvalid)
CPPUNIT_TEST(testParserConstruct)
void testParseRequestLineTerminators()
CPPUNIT_TEST_SUITE(TestHttp1Parser)
void testParseRequestLineMethods()
void testParseRequestLineProtocols()
CPPUNIT_TEST(testDripFeed)
void testParserConstruct()
implements test program's main() function while enabling customization
int run(int argc, char *argv[])
AnyP::ProtocolVersion ProtocolVersion()
Protocol version to use in Http::Message structures wrapping FTP messages.
@ HTTP_PARSE_FIRST
HTTP/1 message first-line.
@ HTTP_PARSE_DONE
parsed a message header, or reached a terminal syntax error
@ HTTP_PARSE_MIME
HTTP/1 mime-header block.
@ HTTP_PARSE_NONE
initialized, but nothing usefully parsed yet
Http1::ParseState parserState
AnyP::ProtocolVersion version
int main(int argc, char *argv[])
CPPUNIT_TEST_SUITE_REGISTRATION(TestHttp1Parser)
static void testResults(int line, const SBuf &input, Http1::RequestParser &output, struct resultSet &expect)