]> 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)
committerSquid Anubis <squid-anubis@squid-cache.org>
Sun, 23 Jun 2019 14:14:51 +0000 (14:14 +0000)
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 e5e1c8f1bfa24c178eb3075cb0aac6b6c76412df..c63fccdf30382dec89ef8c7a534696426e02f3b9 100644 (file)
@@ -491,6 +491,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 4d09a03cc16b7979005b8f6bc1f0b303b5c01314..24f0248d5ef6ac1007d8e7fa96173af597e6b5a1 100644 (file)
@@ -158,8 +158,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
@@ -179,7 +184,9 @@ Http::One::ResponseParser::parseResponseFirstLine()
         return 1; // no more parsing
     }
 
-    return 0; // need more to parse anything.
+    // unreachable
+    assert(false);
+    return -1;
 }
 
 bool