]> 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)
committerJulian Andres Klode <jak@debian.org>
Wed, 5 Oct 2016 19:53:38 +0000 (21:53 +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
(cherry picked from commit 148c049150cc39f2e40894c1684dc2aefea1117e)

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

index 2dc0b54b8f05ab8941506123a1b2a3aa616cedaa..adc242538b970372f61b3a1b45e96eb01c633283 100644 (file)
@@ -102,25 +102,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] == '/')
@@ -164,6 +146,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 3e91406abdbbc98e9f49a2497a662d48294ccb58..2c57877b40b29f74e81c2428d5370425a7604c2d 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)