/*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
#include "anyp/ProtocolVersion.h"
#include "http/one/forward.h"
#include "http/StatusCode.h"
-#include "SBuf.h"
+#include "parser/forward.h"
+#include "sbuf/SBuf.h"
namespace Http {
namespace One {
* Works on a raw character I/O buffer and tokenizes the content into
* the major CRLF delimited segments of an HTTP/1 procotol message:
*
- * \item first-line (request-line / simple-request / status-line)
- * \item mime-header 0*( header-name ':' SP field-value CRLF)
+ * \li first-line (request-line / simple-request / status-line)
+ * \li mime-header 0*( header-name ':' SP field-value CRLF)
*/
class Parser : public RefCountable
{
public:
typedef SBuf::size_type size_type;
+ typedef ::Parser::Tokenizer Tokenizer;
- Parser() : parseStatusCode(Http::scNone), parsingStage_(HTTP_PARSE_NONE) {}
+ Parser() = default;
+ Parser(const Parser &) = default;
+ Parser &operator =(const Parser &) = default;
+ Parser(Parser &&) = default;
+ Parser &operator =(Parser &&) = default;
virtual ~Parser() {}
/// Set this parser back to a default state.
const AnyP::ProtocolVersion & messageProtocol() const {return msgProtocol_;}
/**
- * Scan the mime header block (badly) for a header with the given name.
+ * Scan the mime header block (badly) for a Host header.
*
* BUG: omits lines when searching for headers with obs-fold or multiple entries.
*
*
* \return A pointer to a field-value of the first matching field-name, or NULL.
*/
- char *getHeaderField(const char *name);
+ char *getHostHeaderField();
/// the remaining unprocessed section of buffer
const SBuf &remaining() const {return buf_;}
* Http::scOkay indicates no error,
* other codes represent a parse error.
*/
- Http::StatusCode parseStatusCode;
+ Http::StatusCode parseStatusCode = Http::scNone;
+
+ /// Whitespace between regular protocol elements.
+ /// Seen in RFCs as OWS, RWS, BWS, SP/HTAB but may be "relaxed" by us.
+ /// See also: DelimiterCharacters().
+ static const CharacterSet &WhitespaceCharacters();
+
+ /// Whitespace between protocol elements in restricted contexts like
+ /// request line, status line, asctime-date, and credentials
+ /// Seen in RFCs as SP but may be "relaxed" by us.
+ /// See also: WhitespaceCharacters().
+ /// XXX: Misnamed and overused.
+ static const CharacterSet &DelimiterCharacters();
protected:
- /// detect and skip the CRLF or (if tolerant) LF line terminator
- /// consume from the tokenizer and return true only if found
- bool skipLineTerminator(Http1::Tokenizer &tok) const;
+ /**
+ * detect and skip the CRLF or (if tolerant) LF line terminator
+ * consume from the tokenizer.
+ *
+ * \throws exception on bad or InsuffientInput.
+ * \retval true only if line terminator found.
+ * \retval false incomplete or missing line terminator, need more data.
+ */
+ void skipLineTerminator(Tokenizer &) const;
/**
* Scan to find the mime headers block for current message.
* identified accurately within limit characters.
* mimeHeaderBlock_ has been updated and buf_ consumed.
*
- * \retval false An error occured, or no mime terminator found within limit.
+ * \retval false An error occurred, or no mime terminator found within limit.
*/
bool grabMimeBlock(const char *which, const size_t limit);
SBuf buf_;
/// what stage the parser is currently up to
- ParseState parsingStage_;
+ ParseState parsingStage_ = HTTP_PARSE_NONE;
/// what protocol label has been found in the first line (if any)
AnyP::ProtocolVersion msgProtocol_;
/// buffer holding the mime headers (if any)
SBuf mimeHeaderBlock_;
+
+ /// Whether the invalid HTTP as HTTP/0.9 hack expects a mime header block
+ bool hackExpectsMime_ = false;
+
+private:
+ void cleanMimePrefix();
+ void unfoldMime();
};
+/// skips and, if needed, warns about RFC 7230 BWS ("bad" whitespace)
+/// \throws InsufficientInput when the end of BWS cannot be confirmed
+void ParseBws(Parser::Tokenizer &);
+
+/// the right debugs() level for logging HTTP violation messages
+int ErrorLevel();
+
} // namespace One
} // namespace Http