Преглед на файлове

http(s): allow empty values for header fields

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
David Kalnischkies преди 10 години
родител
ревизия
148c049150
променени са 3 файла, в които са добавени 20 реда и са изтрити 19 реда
  1. 16 19
      methods/server.cc
  2. 1 0
      test/integration/test-bug-778375-server-has-no-reason-phrase
  3. 3 0
      test/interactive-helper/aptwebserver.cc

+ 16 - 19
methods/server.cc

@@ -101,25 +101,7 @@ bool ServerState::HeaderLine(string Line)
    if (Line.empty() == true)
    if (Line.empty() == true)
       return 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
       // Evil servers return no version
       if (Line[4] == '/')
       if (Line[4] == '/')
@@ -163,6 +145,21 @@ bool ServerState::HeaderLine(string Line)
       return true;
       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 (stringcasecmp(Tag,"Content-Length:") == 0)
    {
    {
       if (Encoding == Closes)
       if (Encoding == Closes)

+ 1 - 0
test/integration/test-bug-778375-server-has-no-reason-phrase

@@ -11,6 +11,7 @@ echo 'found' > aptarchive/working
 changetohttpswebserver  -o 'aptwebserver::redirect::replace::/redirectme/=/' \
 changetohttpswebserver  -o 'aptwebserver::redirect::replace::/redirectme/=/' \
 	-o 'aptwebserver::httpcode::200=200' -o 'aptwebserver::httpcode::404=404' \
 	-o 'aptwebserver::httpcode::200=200' -o 'aptwebserver::httpcode::404=404' \
 	-o 'aptwebserver::httpcode::301=301'
 	-o 'aptwebserver::httpcode::301=301'
+webserverconfig 'aptwebserver::empty-response-header::' 'foobar'
 
 
 testdownload() {
 testdownload() {
 	rm -f downfile
 	rm -f downfile

+ 3 - 0
test/interactive-helper/aptwebserver.cc

@@ -122,6 +122,9 @@ static bool sendHead(int const client, int const httpcode, std::list<std::string
    _config->Set("APTWebserver::Last-Status-Code", httpcode);
    _config->Set("APTWebserver::Last-Status-Code", httpcode);
 
 
    std::stringstream buffer;
    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);
    _config->Dump(buffer, "aptwebserver::response-header", "%t: %v%n", false);
    std::vector<std::string> addheaders = VectorizeString(buffer.str(), '\n');
    std::vector<std::string> addheaders = VectorizeString(buffer.str(), '\n');
    for (std::vector<std::string>::const_iterator h = addheaders.begin(); h != addheaders.end(); ++h)
    for (std::vector<std::string>::const_iterator h = addheaders.begin(); h != addheaders.end(); ++h)