X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/dcbb364fc69e1108b3fea3adb12a7ba83d9af467..6257bfdbff8bd15e41b5667a7a10bc123574cb10:/methods/server.cc diff --git a/methods/server.cc b/methods/server.cc index bd01c3e98..e89af2dfe 100644 --- a/methods/server.cc +++ b/methods/server.cc @@ -54,7 +54,7 @@ ServerState::RunHeadersResult ServerState::RunHeaders(FileFd * const File, Major = 0; Minor = 0; Result = 0; - Size = 0; + TotalFileSize = 0; JunkSize = 0; StartPos = 0; Encoding = Closes; @@ -164,15 +164,22 @@ bool ServerState::HeaderLine(string Line) Encoding = Stream; HaveContent = true; - unsigned long long * SizePtr = &Size; + unsigned long long * DownloadSizePtr = &DownloadSize; if (Result == 416) - SizePtr = &JunkSize; + DownloadSizePtr = &JunkSize; - *SizePtr = strtoull(Val.c_str(), NULL, 10); - if (*SizePtr >= std::numeric_limits::max()) + *DownloadSizePtr = strtoull(Val.c_str(), NULL, 10); + if (*DownloadSizePtr >= std::numeric_limits::max()) return _error->Errno("HeaderLine", _("The HTTP server sent an invalid Content-Length header")); - else if (*SizePtr == 0) + else if (*DownloadSizePtr == 0) HaveContent = false; + + // On partial content (206) the Content-Length less than the real + // size, so do not set it here but leave that to the Content-Range + // header instead + if(Result != 206 && TotalFileSize == 0) + TotalFileSize = DownloadSize; + return true; } @@ -187,12 +194,15 @@ bool ServerState::HeaderLine(string Line) HaveContent = true; // §14.16 says 'byte-range-resp-spec' should be a '*' in case of 416 - if (Result == 416 && sscanf(Val.c_str(), "bytes */%llu",&Size) == 1) + if (Result == 416 && sscanf(Val.c_str(), "bytes */%llu",&TotalFileSize) == 1) ; // we got the expected filesize which is all we wanted - else if (sscanf(Val.c_str(),"bytes %llu-%*u/%llu",&StartPos,&Size) != 2) + else if (sscanf(Val.c_str(),"bytes %llu-%*u/%llu",&StartPos,&TotalFileSize) != 2) return _error->Error(_("The HTTP server sent an invalid Content-Range header")); - if ((unsigned long long)StartPos > Size) + if ((unsigned long long)StartPos > TotalFileSize) return _error->Error(_("This HTTP server has broken range support")); + + // figure out what we will download + DownloadSize = TotalFileSize - StartPos; return true; } @@ -242,17 +252,6 @@ bool ServerState::AddPartialFileToHashes(FileFd &File) /*{{{*/ } /*}}}*/ -bool ServerMethod::Configuration(string Message) /*{{{*/ -{ - if (pkgAcqMethod::Configuration(Message) == false) - return false; - - DropPrivsOrDie(); - - return true; -} - /*}}}*/ - // ServerMethod::DealWithHeaders - Handle the retrieved header data /*{{{*/ // --------------------------------------------------------------------- /* We look at the header data we got back from the server and decide what @@ -264,7 +263,7 @@ ServerMethod::DealWithHeaders(FetchResult &Res) // Not Modified if (Server->Result == 304) { - unlink(Queue->DestFile.c_str()); + RemoveFile("server", Queue->DestFile); Res.IMSHit = true; Res.LastModified = Queue->LastModified; return IMS_HIT; @@ -319,13 +318,13 @@ ServerMethod::DealWithHeaders(FetchResult &Res) { Hashes resultHashes(Queue->ExpectedHashes); FileFd file(Queue->DestFile, FileFd::ReadOnly); - Server->Size = file.FileSize(); + Server->TotalFileSize = file.FileSize(); Server->Date = file.ModificationTime(); resultHashes.AddFD(file); HashStringList const hashList = resultHashes.GetHashStringList(); partialHit = (Queue->ExpectedHashes == hashList); } - else if ((unsigned long long)SBuf.st_size == Server->Size) + else if ((unsigned long long)SBuf.st_size == Server->TotalFileSize) partialHit = true; if (partialHit == true) { @@ -337,10 +336,10 @@ ServerMethod::DealWithHeaders(FetchResult &Res) Server->RunData(&DevNull); } Server->HaveContent = false; - Server->StartPos = Server->Size; + Server->StartPos = Server->TotalFileSize; Server->Result = 200; } - else if (unlink(Queue->DestFile.c_str()) == 0) + else if (RemoveFile("server", Queue->DestFile)) { NextURI = Queue->Uri; return TRY_AGAIN_OR_REDIRECT; @@ -348,7 +347,7 @@ ServerMethod::DealWithHeaders(FetchResult &Res) } } - /* We have a reply we dont handle. This should indicate a perm server + /* We have a reply we don't handle. This should indicate a perm server failure */ if (Server->Result < 200 || Server->Result >= 300) { @@ -363,8 +362,8 @@ ServerMethod::DealWithHeaders(FetchResult &Res) // This is some sort of 2xx 'data follows' reply Res.LastModified = Server->Date; - Res.Size = Server->Size; - + Res.Size = Server->TotalFileSize; + // Open the file delete File; File = new FileFd(Queue->DestFile,FileFd::WriteAny); @@ -372,7 +371,7 @@ ServerMethod::DealWithHeaders(FetchResult &Res) return ERROR_NOT_FROM_SERVER; FailFile = Queue->DestFile; - FailFile.c_str(); // Make sure we dont do a malloc in the signal handler + FailFile.c_str(); // Make sure we don't do a malloc in the signal handler FailFd = File->Fd(); FailTime = Server->Date; @@ -485,10 +484,8 @@ int ServerMethod::Loop() // Connect to the server if (Server == 0 || Server->Comp(Queue->Uri) == false) - { - delete Server; Server = CreateServerState(Queue->Uri); - } + /* If the server has explicitly said this is the last connection then we pre-emptively shut down the pipeline and tear down the connection. This will speed up HTTP/1.0 servers a tad @@ -505,8 +502,7 @@ int ServerMethod::Loop() if (Server->Open() == false) { Fail(true); - delete Server; - Server = 0; + Server = nullptr; continue; } @@ -738,9 +734,7 @@ int ServerMethod::Loop() return 0; } /*}}}*/ - /*{{{*/ -unsigned long long -ServerMethod::FindMaximumObjectSizeInQueue() const +unsigned long long ServerMethod::FindMaximumObjectSizeInQueue() const /*{{{*/ { unsigned long long MaxSizeInQueue = 0; for (FetchItem *I = Queue; I != 0 && I != QueueBack; I = I->Next) @@ -748,3 +742,9 @@ ServerMethod::FindMaximumObjectSizeInQueue() const return MaxSizeInQueue; } /*}}}*/ +ServerMethod::ServerMethod(char const * const Binary, char const * const Ver,unsigned long const Flags) :/*{{{*/ + aptMethod(Binary, Ver, Flags), Server(nullptr), File(NULL), PipelineDepth(10), + AllowRedirect(false), Debug(false) +{ +} + /*}}}*/