]> git.saurik.com Git - apt.git/commitdiff
http(s): allow empty values for header fields
authorDavid Kalnischkies <david@kalnischkies.de>
Fri, 12 Aug 2016 20:13:09 +0000 (22:13 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Sat, 13 Aug 2016 06:49:35 +0000 (08:49 +0200)
It seems completely pointless from a server-POV to sent empty header
fields, so most of them don't do it (simply proven by this limitation
existing since day one) – but it is technically allowed by the RFC as
the surounding whitespaces are optional and Github seems to like sending
"X-Geo-Block-List:\r\n" since recently (bug reports in other http
clients indicate July) at least sometimes as the reporter claims to have
seen it on https only even through it can happen with both.

Closes: 834048
methods/server.cc
test/integration/test-bug-778375-server-has-no-reason-phrase
test/interactive-helper/aptwebserver.cc

index 0888617b1f1f2b2ddf5744c74cc221cbbfee071e..3f0e8845751ad0702c9789f6afa544ba671dde2b 100644 (file)
@@ -101,25 +101,7 @@ bool ServerState::HeaderLine(string Line)
    if (Line.empty() == true)
       return true;
 
-   string::size_type Pos = Line.find(' ');
-   if (Pos == string::npos || Pos+1 > Line.length())
-   {
-      // Blah, some servers use "connection:closes", evil.
-      Pos = Line.find(':');
-      if (Pos == string::npos || Pos + 2 > Line.length())
-        return _error->Error(_("Bad header line"));
-      Pos++;
-   }
-
-   // Parse off any trailing spaces between the : and the next word.
-   string::size_type Pos2 = Pos;
-   while (Pos2 < Line.length() && isspace_ascii(Line[Pos2]) != 0)
-      Pos2++;
-
-   string Tag = string(Line,0,Pos);
-   string Val = string(Line,Pos2);
-
-   if (stringcasecmp(Tag.c_str(),Tag.c_str()+4,"HTTP") == 0)
+   if (Line.size() > 4 && stringcasecmp(Line.data(), Line.data()+4, "HTTP") == 0)
    {
       // Evil servers return no version
       if (Line[4] == '/')
@@ -163,6 +145,21 @@ bool ServerState::HeaderLine(string Line)
       return true;
    }
 
+   // Blah, some servers use "connection:closes", evil.
+   // and some even send empty header fields…
+   string::size_type Pos = Line.find(':');
+   if (Pos == string::npos)
+      return _error->Error(_("Bad header line"));
+   ++Pos;
+
+   // Parse off any trailing spaces between the : and the next word.
+   string::size_type Pos2 = Pos;
+   while (Pos2 < Line.length() && isspace_ascii(Line[Pos2]) != 0)
+      Pos2++;
+
+   string const Tag(Line,0,Pos);
+   string const Val(Line,Pos2);
+
    if (stringcasecmp(Tag,"Content-Length:") == 0)
    {
       if (Encoding == Closes)
index bce41235f3393fd200dc0f2567f717b2dc8144d4..28e31e0691c53e90ab8e381ba17af3af1b8a9ff9 100755 (executable)
@@ -11,6 +11,7 @@ echo 'found' > aptarchive/working
 changetohttpswebserver  -o 'aptwebserver::redirect::replace::/redirectme/=/' \
        -o 'aptwebserver::httpcode::200=200' -o 'aptwebserver::httpcode::404=404' \
        -o 'aptwebserver::httpcode::301=301'
+webserverconfig 'aptwebserver::empty-response-header::' 'foobar'
 
 testdownload() {
        rm -f downfile
index 817760ec309e57ecbe1c072d4c98a5b71ab19b56..c32f286b20a6c08daa7553021eaed5ce947ceb2f 100644 (file)
@@ -122,6 +122,9 @@ static bool sendHead(int const client, int const httpcode, std::list<std::string
    _config->Set("APTWebserver::Last-Status-Code", httpcode);
 
    std::stringstream buffer;
+   auto const empties = _config->FindVector("aptwebserver::empty-response-header");
+   for (auto && e: empties)
+      buffer << e << ":" << std::endl;
    _config->Dump(buffer, "aptwebserver::response-header", "%t: %v%n", false);
    std::vector<std::string> addheaders = VectorizeString(buffer.str(), '\n');
    for (std::vector<std::string>::const_iterator h = addheaders.begin(); h != addheaders.end(); ++h)