54 if (!completedStatus_) {
55 debugs(74, 9,
"seek status-code in: " <<
tok.remaining().substr(0,10) <<
"...");
56 ParseResponseStatus(
tok, statusCode_);
57 buf_ =
tok.remaining();
58 completedStatus_ =
true;
68 debugs(74, 9,
"seek reason-phrase in: " <<
tok.remaining().substr(0,50) <<
"...");
71 (void)
tok.prefix(reasonPhrase_, phraseChars);
72 skipLineTerminator(
tok);
73 buf_ =
tok.remaining();
76 }
catch (
const InsufficientInput &) {
77 reasonPhrase_.clear();
79 }
catch (
const std::exception &ex) {
80 debugs(74, 6,
"invalid status-line: " << ex.what());
90 debugs(74, 6,
"raw status-code=" << statusValue);
102 }
else if (
tok.atEnd()) {
103 throw InsufficientInput();
130 debugs(74, 6,
"continue incremental parse for " << msgProtocol_);
131 debugs(74,
DBG_DATA,
"parse remaining buf={length=" <<
tok.remaining().length() <<
", data='" <<
tok.remaining() <<
"'}");
133 return parseResponseStatusAndReason(
tok);
135 }
else if (
tok.skip(Http1magic)) {
136 debugs(74, 6,
"found prefix magic " << Http1magic);
141 const auto &WspDelim = DelimiterCharacters();
142 if (
tok.int64(verMinor, 10,
false, 1) &&
tok.skipOne(WspDelim)) {
144 msgProtocol_.major = 1;
145 msgProtocol_.minor =
static_cast<unsigned int>(verMinor);
147 debugs(74, 6,
"found version=" << msgProtocol_);
149 debugs(74,
DBG_DATA,
"parse remaining buf={length=" <<
tok.remaining().length() <<
", data='" <<
tok.remaining() <<
"'}");
150 buf_ =
tok.remaining();
151 return parseResponseStatusAndReason(
tok);
153 }
else if (
tok.atEnd())
158 }
else if (
tok.skip(IcyMagic)) {
159 debugs(74, 6,
"found prefix magic " << IcyMagic);
163 debugs(74,
DBG_DATA,
"parse remaining buf={length=" <<
tok.remaining().length() <<
", data='" <<
tok.remaining() <<
"'}");
164 buf_ =
tok.remaining();
165 return parseResponseStatusAndReason(
tok);
166 }
else if (buf_.length() < Http1magic.length() && Http1magic.startsWith(buf_)) {
167 debugs(74, 7,
Raw(
"valid HTTP/1 prefix", buf_.rawContent(), buf_.length()));
169 }
else if (buf_.length() < IcyMagic.length() && IcyMagic.startsWith(buf_)) {
170 debugs(74, 7,
Raw(
"valid ICY prefix", buf_.rawContent(), buf_.length()));
173 debugs(74, 2,
"unknown/missing prefix magic. Interpreting as HTTP/0.9");
180 static const SBuf gatewayPhrase(
"Gatewaying");
181 reasonPhrase_ = gatewayPhrase;
182 static const SBuf fakeHttpMimeBlock(
"X-Transformed-From: HTTP/0.9\r\n"
184 "Mime-Version: 1.0\r\n"
186 "Expires: -1\r\n\r\n");
187 mimeHeaderBlock_ = fakeHttpMimeBlock;
217 const int retcode = parseResponseFirstLine();
222 debugs(74, 5,
"status-line: retval " << retcode);
223 debugs(74, 5,
"status-line: proto " << msgProtocol_);
224 debugs(74, 5,
"status-line: status-code " << statusCode_);
225 debugs(74, 5,
"status-line: reason-phrase " << reasonPhrase_);
226 debugs(74, 5,
"Parser: bytes processed=" << (aBuf.
length()-buf_.length()));
242 return !needsMoreData();
#define Here()
source code location of the caller
ProtocolType protocol
which protocol this version is for
unsigned int minor
minor version number
optimized set of C chars, with quick membership test and merge support
static const CharacterSet WSP
static const CharacterSet VCHAR
static const CharacterSet OBSTEXT
SBuf::size_type size_type
AnyP::ProtocolVersion msgProtocol_
what protocol label has been found in the first line (if any)
static const CharacterSet & DelimiterCharacters()
::Parser::Tokenizer Tokenizer
static const SBuf Http1magic
RFC 7230 section 2.6 - 7 magic octets.
SBuf reasonPhrase_
HTTP/1 status-line reason phrase.
int parseResponseStatusAndReason(Tokenizer &)
static void ParseResponseStatus(Tokenizer &, StatusCode &code)
Http1::Parser::size_type firstLineSize() const override
size in bytes of the first line including CRLF terminator
static const SBuf IcyMagic
magic prefix for identifying ICY response messages
int parseResponseFirstLine()
bool parse(const SBuf &aBuf) override
size_type length() const
Returns the number of bytes stored in SBuf.
size_t maxReplyHeaderSize
an std::runtime_error with thrower location info
#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
AnyP::ProtocolVersion ProtocolVersion(unsigned int aMajor, unsigned int aMinor)
HTTP version label information.
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf