]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Rearrange PROXY/1.0 parser
authorAmos Jeffries <squid3@treenet.co.nz>
Wed, 13 Aug 2014 14:35:32 +0000 (07:35 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Wed, 13 Aug 2014 14:35:32 +0000 (07:35 -0700)
Add a first pass to confirm LF line terminator and wait for more bytes if
missing.

src/client_side.cc

index 3945381553acb259b0088143d3461dc8e5edbe38..a183790db2fde892ec3c7a029dc95b31339a3ef5 100644 (file)
@@ -2986,17 +2986,33 @@ ConnStateData::parseProxy1p0()
     ::Parser::Tokenizer tok(in.buf);
     tok.skip(Proxy1p0magic);
 
+    // skip to first LF (assumes it is part of CRLF)
+    static const CharacterSet lineContent = CharacterSet::LF.complement("non-LF");
+    SBuf line;
+    if (tok.prefix(line, lineContent, 107-Proxy1p0magic.length())) {
+        if (tok.skip('\n')) {
+            // found valid header
+            in.buf = tok.remaining();
+            needProxyProtocolHeader_ = false;
+            // reset the tokenizer to work on found line only.
+            tok.reset(line);
+        } else
+            return false; // no LF yet
+
+    } else // protocol error only if there are more than 107 bytes prefix header
+        return proxyProtocolError(in.buf.length() > 107? "PROXY/1.0 error: missing CRLF" : NULL);
+
     static const SBuf unknown("UNKNOWN"), tcpName("TCP");
     if (tok.skip(tcpName)) {
 
         // skip TCP/IP version number
         static const CharacterSet tcpVersions("TCP-version","46");
         if(!tok.skipOne(tcpVersions))
-            return proxyProtocolError(tok.atEnd() ? "PROXY/1.0 error: missing TCP version" : NULL);
+            return proxyProtocolError("PROXY/1.0 error: missing TCP version");
 
         // skip SP after protocol version
         if (!tok.skip(' '))
-            return proxyProtocolError(tok.atEnd() ? "PROXY/1.0 error: missing SP" : NULL);
+            return proxyProtocolError("PROXY/1.0 error: missing SP");
 
         SBuf ipa, ipb;
         int64_t porta, portb;
@@ -3010,13 +3026,7 @@ ConnStateData::parseProxy1p0()
                              tok.int64(portb) &&
                              tok.skip('\r');
         if (!correct)
-            return proxyProtocolError(!tok.atEnd() ? "PROXY/1.0 error: invalid syntax" : NULL);
-
-        if (!tok.skip('\n')) // line terminator.
-            return proxyProtocolError("PROXY/1.0 error: missing LF");
-
-        in.buf = tok.remaining(); // sync buffers
-        needProxyProtocolHeader_ = false; // found successfully
+            return proxyProtocolError("PROXY/1.0 error: invalid syntax");
 
         // parse IP and port strings
         Ip::Address originalClient, originalDest;
@@ -3052,23 +3062,11 @@ ConnStateData::parseProxy1p0()
         return true;
 
     } else if (tok.skip(unknown)) {
-        // skip to first LF (assumes it is part of CRLF)
-        const SBuf::size_type pos = in.buf.findFirstOf(CharacterSet::LF);
-        if (pos != SBuf::npos) {
-            if (in.buf[pos-1] != '\r')
-                return proxyProtocolError("PROXY/1.0 error: missing CR");
-            // found valid but unusable header
-            in.buf.consume(pos);
-            needProxyProtocolHeader_ = false;
-            return true;
-        }
-        // else, no LF found
-
-        // protocol error only if there are more than 107 bytes prefix header
-        return proxyProtocolError(in.buf.length() > 107? "PROXY/1.0 error: missing CRLF":NULL);
+        // found valid but unusable header
+        return true;
 
     } else
-        return proxyProtocolError(tok.atEnd() ? "PROXY/1.0 error: invalid protocol family" : NULL);
+        return proxyProtocolError("PROXY/1.0 error: invalid protocol family");
 
     return false;
 }