From e8121b2281301d4704129d81ecfdca959611c333 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Sun, 23 Jun 2019 14:14:47 +0000 Subject: [PATCH] Fix handling of tiny invalid responses (#422) Squid converted any invalid response shorter than 4 bytes into an invalid "HTTP/1.1 0 Init" response (with those received characters and a CRLFCRLF suffix as a body). In some cases (e.g., with ICAP RESPMOD), the resulting body was not sent to the client at all. Now Squid handles such responses the same way it handles any non-HTTP/1 (and non-ICY) response, converting it into a valid HTTP/200 response with an X-Transformed-From:HTTP/0.9 header and received bytes as a message body. --- src/HttpReply.cc | 1 + src/http/one/ResponseParser.cc | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/HttpReply.cc b/src/HttpReply.cc index e007bc05e1..9ff4deadcb 100644 --- a/src/HttpReply.cc +++ b/src/HttpReply.cc @@ -477,6 +477,7 @@ HttpReply::expectingBody(const HttpRequestMethod& req_method, int64_t& theSize) expectBody = false; else if (sline.status() == Http::scNotModified) expectBody = false; + // TODO: Consider assuming that gray-area 0xx responses have bodies, like 9xx responses. else if (sline.status() < Http::scOkay) expectBody = false; else diff --git a/src/http/one/ResponseParser.cc b/src/http/one/ResponseParser.cc index 4dcaafb270..a548134c9d 100644 --- a/src/http/one/ResponseParser.cc +++ b/src/http/one/ResponseParser.cc @@ -159,8 +159,13 @@ Http::One::ResponseParser::parseResponseFirstLine() debugs(74, DBG_DATA, "parse remaining buf={length=" << tok.remaining().length() << ", data='" << tok.remaining() << "'}"); buf_ = tok.remaining(); // resume checkpoint return parseResponseStatusAndReason(tok, WspDelim); - - } else if (buf_.length() > Http1magic.length() && buf_.length() > IcyMagic.length()) { + } else if (buf_.length() < Http1magic.length() && Http1magic.startsWith(buf_)) { + debugs(74, 7, Raw("valid HTTP/1 prefix", buf_.rawContent(), buf_.length())); + return 0; + } else if (buf_.length() < IcyMagic.length() && IcyMagic.startsWith(buf_)) { + debugs(74, 7, Raw("valid ICY prefix", buf_.rawContent(), buf_.length())); + return 0; + } else { debugs(74, 2, "unknown/missing prefix magic. Interpreting as HTTP/0.9"); // found something that looks like an HTTP/0.9 response // Gateway/Transform it into HTTP/1.1 @@ -180,7 +185,9 @@ Http::One::ResponseParser::parseResponseFirstLine() return 1; // no more parsing } - return 0; // need more to parse anything. + // unreachable + assert(false); + return -1; } bool -- 2.47.2