]> git.saurik.com Git - apt.git/blobdiff - methods/server.cc
close server if parsing of header field failed
[apt.git] / methods / server.cc
index 322b8d94ca1dfcdd98f20ff20715aa1659437a97..5ab97a66037c1dcc8f56a6d6d1a45b4a03eadb85 100644 (file)
@@ -10,7 +10,6 @@
 // Include Files                                                       /*{{{*/
 #include <config.h>
 
-#include <apt-pkg/acquire-method.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/fileutl.h>
@@ -130,7 +129,7 @@ bool ServerState::HeaderLine(string Line)
         {
            Code[0] = '\0';
            if (Owner != NULL && Owner->Debug == true)
-              clog << "HTTP server doesn't give Reason-Phrase for " << Result << std::endl;
+              clog << "HTTP server doesn't give Reason-Phrase for " << std::to_string(Result) << std::endl;
         }
         else if (elements != 4)
            return _error->Error(_("The HTTP server sent an invalid reply header"));
@@ -419,36 +418,66 @@ void ServerMethod::SigTerm(int)
    depth. */
 bool ServerMethod::Fetch(FetchItem *)
 {
-   if (Server == 0)
+   if (Server == nullptr || QueueBack == nullptr)
       return true;
 
-   // Queue the requests
-   int Depth = -1;
-   for (FetchItem *I = Queue; I != 0 && Depth < (signed)PipelineDepth; 
-       I = I->Next, Depth++)
-   {
-      if (Depth >= 0)
-      {
-        // If pipelining is disabled, we only queue 1 request
-        if (Server->Pipeline == false)
-           break;
-        // if we have no hashes, do at most one such request
-        // as we can't fixup pipeling misbehaviors otherwise
-        else if (I->ExpectedHashes.usable() == false)
-           break;
-      }
-      
+   // If pipelining is disabled, we only queue 1 request
+   auto const AllowedDepth = Server->Pipeline ? PipelineDepth : 0;
+   // how deep is our pipeline currently?
+   decltype(PipelineDepth) CurrentDepth = 0;
+   for (FetchItem const *I = Queue; I != QueueBack; I = I->Next)
+      ++CurrentDepth;
+
+   do {
       // Make sure we stick with the same server
-      if (Server->Comp(I->Uri) == false)
+      if (Server->Comp(QueueBack->Uri) == false)
+        break;
+
+      bool const UsableHashes = QueueBack->ExpectedHashes.usable();
+      // if we have no hashes, do at most one such request
+      // as we can't fixup pipeling misbehaviors otherwise
+      if (CurrentDepth != 0 && UsableHashes == false)
         break;
-      if (QueueBack == I)
+
+      if (UsableHashes && FileExists(QueueBack->DestFile))
       {
-        QueueBack = I->Next;
-        SendReq(I);
-        continue;
+        FileFd partial(QueueBack->DestFile, FileFd::ReadOnly);
+        Hashes wehave(QueueBack->ExpectedHashes);
+        if (QueueBack->ExpectedHashes.FileSize() == partial.FileSize())
+        {
+           if (wehave.AddFD(partial) &&
+                 wehave.GetHashStringList() == QueueBack->ExpectedHashes)
+           {
+              FetchResult Res;
+              Res.Filename = QueueBack->DestFile;
+              Res.ResumePoint = QueueBack->ExpectedHashes.FileSize();
+              URIStart(Res);
+              // move item to the start of the queue as URIDone will
+              // always dequeued the first item in the queue
+              if (Queue != QueueBack)
+              {
+                 FetchItem *Prev = Queue;
+                 for (; Prev->Next != QueueBack; Prev = Prev->Next)
+                    /* look for the previous queue item */;
+                 Prev->Next = QueueBack->Next;
+                 QueueBack->Next = Queue;
+                 Queue = QueueBack;
+                 QueueBack = Prev->Next;
+              }
+              Res.TakeHashes(wehave);
+              URIDone(Res);
+              continue;
+           }
+           else
+              RemoveFile("Fetch-Partial", QueueBack->DestFile);
+        }
       }
-   }
-   
+      auto const Tmp = QueueBack;
+      QueueBack = QueueBack->Next;
+      SendReq(Tmp);
+      ++CurrentDepth;
+   } while (CurrentDepth <= AllowedDepth && QueueBack != nullptr);
+
    return true;
 }
                                                                        /*}}}*/
@@ -527,6 +556,7 @@ int ServerMethod::Loop()
         {
            _error->Error(_("Bad header data"));
            Fail(true);
+           Server->Close();
            RotateDNS();
            continue;
         }