]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Fix handling of tiny invalid responses (#422)
authorEduard Bagdasaryan <eduard.bagdasaryan@measurement-factory.com>
Sun, 23 Jun 2019 14:14:47 +0000 (14:14 +0000)
committerAmos Jeffries <yadij@users.noreply.github.com>
Thu, 4 Jul 2019 11:01:16 +0000 (23:01 +1200)
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
src/http/one/ResponseParser.cc

index e007bc05e19da22d2441a195c1a3e9ab9eae803e..9ff4deadcba6af027e306f1e044d2e783644f06f 100644 (file)
@@ -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
index 4dcaafb270e0acdc8b2f47be3e2ea8ad712bdcda..a548134c9d6699b328ae5ce696459c142056fbeb 100644 (file)
@@ -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