43 "CRLF bytes received ahead of request-line. " <<
44 "Ignored due to relaxed_header_parser.");
47 while (!buf_.isEmpty() && (buf_[0] ==
'\n' ||
48 (buf_[0] ==
'\r' && buf_.length() > 1 && buf_[1] ==
'\n'))) {
69 static const size_t maxMethodLength = 32;
73 debugs(33,
ErrorLevel(),
"ERROR: invalid request-line: missing or malformed method");
79 if (!skipDelimiter(
tok.skipAll(DelimiterCharacters()),
"after method"))
116#if USE_HTTP_VIOLATIONS
120 DelimiterCharacters() +
127 return RelaxedExtended;
132 DelimiterCharacters();
134 return RelaxedCompliant;
154 const size_t maxUriLength =
static_cast<size_t>((64*1024)-1);
157 if (!
tok.prefix(uriFound, RequestTargetCharacters())) {
159 debugs(33,
ErrorLevel(),
"ERROR: invalid request-line: missing or malformed URI");
163 if (uriFound.
length() > maxUriLength) {
167 "-byte URI exceeds " << maxUriLength <<
"-byte limit");
178 static const SBuf http1p0(
"HTTP/1.0");
179 static const SBuf http1p1(
"HTTP/1.1");
180 const auto savedTok =
tok;
184 if (
tok.skipSuffix(http1p1)) {
187 }
else if (
tok.skipSuffix(http1p0)) {
194 static const SBuf proto(
"HTTP/");
198 tok.skipOneTrailing(period) &&
200 tok.skipSuffix(proto)) {
201 const bool multiDigits = majorDigit.
length() > 1 || minorDigit.
length() > 1;
203 const unsigned int major = multiDigits ? 0 : (*majorDigit.
rawContent() -
'0');
204 const unsigned int minor = multiDigits ? 0 : (*minorDigit.
rawContent() -
'0');
234 debugs(33,
ErrorLevel(),
"ERROR: invalid request-line: missing delimiter " << where);
241 debugs(33,
ErrorLevel(),
"ERROR: invalid request-line: too many delimiters " << where);
257 debugs(33,
ErrorLevel(),
"ERROR: invalid request-line: missing CR before LF");
279 debugs(74, 5,
"parsing possible request: buf.length=" << buf_.length());
288 if (!lineTok.prefix(line, lineChars) || !lineTok.skip(
'\n')) {
293 if (!parseMethodField(methodTok))
302 debugs(74, 5,
"Parser needs more data");
308 if (!parseMethodField(
tok))
312 if (!skipTrailingCrs(
tok))
315 if (!parseHttpVersionField(
tok))
318 if (!http0() && !skipDelimiter(
tok.skipAllTrailing(DelimiterCharacters()),
"before protocol version"))
323 if (!parseUriField(
tok))
333 buf_ = lineTok.remaining();
340 const bool result = doParse(aBuf);
341 if (preserveParsed_) {
343 parsed_.append(aBuf.
substr(0, aBuf.
length() - remaining().length()));
369 const int retcode = parseRequestFirstLine();
376 debugs(74, 5,
"request-line: retval " << retcode <<
": line={" << aBuf.
length() <<
", data='" << aBuf <<
"'}");
377 debugs(74, 5,
"request-line: method: " << method_);
378 debugs(74, 5,
"request-line: url: " << uri_);
379 debugs(74, 5,
"request-line: proto: " << msgProtocol_);
380 debugs(74, 5,
"Parser: bytes processed=" << (aBuf.
length()-buf_.length()));
399 return !needsMoreData();
static const CharacterSet & UriValidCharacters()
the characters which truly are valid within URI
optimized set of C chars, with quick membership test and merge support
CharacterSet complement(const char *complementLabel=nullptr) const
static const CharacterSet TCHAR
static const CharacterSet DIGIT
static const CharacterSet ALPHA
static const CharacterSet HEXDIG
static const CharacterSet LF
static const CharacterSet CR
const SBuf & image() const
SBuf::size_type size_type
::Parser::Tokenizer Tokenizer
bool parseMethodField(Tokenizer &)
bool doParse(const SBuf &aBuf)
called from parse() to do the parsing
Http1::Parser::size_type firstLineSize() const override
size in bytes of the first line including CRLF terminator
static const CharacterSet & RequestTargetCharacters()
characters which Squid will accept in the HTTP request-target (URI)
bool parse(const SBuf &aBuf) override
bool skipDelimiter(const size_t count, const char *where)
int parseRequestFirstLine()
bool parseHttpVersionField(Tokenizer &)
HttpRequestMethod method_
what request method has been found on the first line
bool parseUriField(Tokenizer &)
SBuf uri_
raw copy of the original client request-line URI field
bool skipTrailingCrs(Tokenizer &tok)
Parse CRs at the end of request-line, just before the terminating LF.
const char * rawContent() const
size_type length() const
Returns the number of bytes stored in SBuf.
SBuf substr(size_type pos, size_type n=npos) const
struct SquidConfig::@106 onoff
size_t maxRequestHeaderSize
int relaxed_header_parser
#define debugs(SECTION, LEVEL, CONTENT)
@ 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
int ErrorLevel()
the right debugs() level for logging HTTP violation messages
@ scRequestHeaderFieldsTooLarge
AnyP::ProtocolVersion ProtocolVersion(unsigned int aMajor, unsigned int aMinor)
HTTP version label information.