]> git.saurik.com Git - apt.git/blobdiff - methods/server.cc
You have to do the bounds check before the access.
[apt.git] / methods / server.cc
index 3f0e8845751ad0702c9789f6afa544ba671dde2b..0408dddfd3f8dfbb8ef395f1b3d8935e8cac712e 100644 (file)
@@ -46,20 +46,9 @@ time_t ServerMethod::FailTime = 0;
 ServerState::RunHeadersResult ServerState::RunHeaders(FileFd * const File,
                                                       const std::string &Uri)
 {
-   State = Header;
-   
+   Reset(false);
    Owner->Status(_("Waiting for headers"));
 
-   Major = 0; 
-   Minor = 0; 
-   Result = 0; 
-   TotalFileSize = 0;
-   JunkSize = 0;
-   StartPos = 0;
-   Encoding = Closes;
-   HaveContent = false;
-   time(&Date);
-
    do
    {
       string Data;
@@ -219,8 +208,16 @@ bool ServerState::HeaderLine(string Line)
    if (stringcasecmp(Tag,"Connection:") == 0)
    {
       if (stringcasecmp(Val,"close") == 0)
+      {
         Persistent = false;
-      if (stringcasecmp(Val,"keep-alive") == 0)
+        Pipeline = false;
+        /* Some servers send error pages (as they are dynamically generated)
+           for simplicity via a connection close instead of e.g. chunked,
+           so assuming an always closing server only if we get a file + close */
+        if (Result >= 200 && Result < 300)
+           PipelineAllowed = false;
+      }
+      else if (stringcasecmp(Val,"keep-alive") == 0)
         Persistent = true;
       return true;
    }
@@ -238,6 +235,15 @@ bool ServerState::HeaderLine(string Line)
       return true;
    }
 
+   if (stringcasecmp(Tag, "Accept-Ranges:") == 0)
+   {
+      std::string ranges = ',' + Val + ',';
+      ranges.erase(std::remove(ranges.begin(), ranges.end(), ' '), ranges.end());
+      if (ranges.find(",bytes,") == std::string::npos)
+        RangesAllowed = false;
+      return true;
+   }
+
    return true;
 }
                                                                        /*}}}*/
@@ -254,6 +260,19 @@ bool ServerState::AddPartialFileToHashes(FileFd &File)                     /*{{{*/
    return GetHashes()->AddFD(File, StartPos);
 }
                                                                        /*}}}*/
+void ServerState::Reset(bool const Everything)                         /*{{{*/
+{
+   Major = 0; Minor = 0; Result = 0; Code[0] = '\0';
+   TotalFileSize = 0; JunkSize = 0; StartPos = 0;
+   Encoding = Closes; time(&Date); HaveContent = false;
+   State = Header; MaximumSize = 0;
+   if (Everything)
+   {
+      Persistent = false; Pipeline = false; PipelineAllowed = true;
+      RangesAllowed = true;
+   }
+}
+                                                                       /*}}}*/
 
 // ServerMethod::DealWithHeaders - Handle the retrieved header data    /*{{{*/
 // ---------------------------------------------------------------------
@@ -751,8 +770,8 @@ int ServerMethod::Loop()
         // We need to flush the data, the header is like a 404 w/ error text
         case ERROR_WITH_CONTENT_PAGE:
         {
-           Fail();
            Server->RunDataToDevNull();
+           Fail();
            break;
         }