diff options
author | Michael Vogt <mvo@ubuntu.com> | 2015-05-22 17:01:03 +0200 |
---|---|---|
committer | Michael Vogt <mvo@ubuntu.com> | 2015-05-22 17:01:03 +0200 |
commit | 4fc6b7570c3e97b65c118b58cdf6729fa94c9b03 (patch) | |
tree | f952bb728b9c23f1eebc8f1a87f527ed7c9b0b36 /methods | |
parent | 6bf93605fdb8e858d3f0a79a124c1d39f760094d (diff) | |
parent | 65759e00eff0513c34f584b99420b72fe0e5073e (diff) |
Merge branch 'debian/sid' into debian/experimental
Conflicts:
apt-pkg/pkgcache.h
debian/changelog
methods/https.cc
methods/server.cc
test/integration/test-apt-download-progress
Diffstat (limited to 'methods')
-rw-r--r-- | methods/http.cc | 2 | ||||
-rw-r--r-- | methods/https.cc | 8 | ||||
-rw-r--r-- | methods/server.cc | 38 | ||||
-rw-r--r-- | methods/server.h | 13 |
4 files changed, 39 insertions, 22 deletions
diff --git a/methods/http.cc b/methods/http.cc index af3d5ccb6..ce697a338 100644 --- a/methods/http.cc +++ b/methods/http.cc @@ -447,7 +447,7 @@ bool HttpServerState::RunData(FileFd * const File) else if (JunkSize != 0) In.Limit(JunkSize); else - In.Limit(Size - StartPos); + In.Limit(DownloadSize); // Just transfer the whole block. do diff --git a/methods/https.cc b/methods/https.cc index fa143439a..d2ddf6fcf 100644 --- a/methods/https.cc +++ b/methods/https.cc @@ -70,19 +70,19 @@ HttpsMethod::parse_header(void *buffer, size_t size, size_t nmemb, void *userp) { Hashes resultHashes(me->Itm->ExpectedHashes); FileFd file(me->Itm->DestFile, FileFd::ReadOnly); - me->https->Server->Size = file.FileSize(); + me->https->Server->TotalFileSize = file.FileSize(); me->https->Server->Date = file.ModificationTime(); resultHashes.AddFD(file); HashStringList const hashList = resultHashes.GetHashStringList(); partialHit = (me->Itm->ExpectedHashes == hashList); } - else if (me->https->Server->Result == 416 && me->https->Server->Size == me->https->File->FileSize()) + else if (me->https->Server->Result == 416 && me->https->Server->TotalFileSize == me->https->File->FileSize()) partialHit = true; if (partialHit == true) { me->https->Server->Result = 200; - me->https->Server->StartPos = me->https->Server->Size; + me->https->Server->StartPos = me->https->Server->TotalFileSize; // the actual size is not important for https as curl will deal with it // by itself and e.g. doesn't bother us with transport-encoding… me->https->Server->JunkSize = std::numeric_limits<unsigned long long>::max(); @@ -94,7 +94,7 @@ HttpsMethod::parse_header(void *buffer, size_t size, size_t nmemb, void *userp) me->https->Server->StartPos = 0; me->Res->LastModified = me->https->Server->Date; - me->Res->Size = me->https->Server->Size; + me->Res->Size = me->https->Server->TotalFileSize; me->Res->ResumePoint = me->https->Server->StartPos; // we expect valid data, so tell our caller we get the file now diff --git a/methods/server.cc b/methods/server.cc index bd01c3e98..f61a6fedb 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<unsigned long long>::max()) + *DownloadSizePtr = strtoull(Val.c_str(), NULL, 10); + if (*DownloadSizePtr >= std::numeric_limits<unsigned long long>::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; } @@ -319,13 +329,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,7 +347,7 @@ 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) @@ -363,8 +373,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); diff --git a/methods/server.h b/methods/server.h index 1b1f754a3..8d7d33ee6 100644 --- a/methods/server.h +++ b/methods/server.h @@ -34,9 +34,16 @@ struct ServerState char Code[360]; // These are some statistics from the last parsed header lines - unsigned long long Size; // size of the usable content (aka: the file) - unsigned long long JunkSize; // size of junk content (aka: server error pages) + + // total size of the usable content (aka: the file) + unsigned long long TotalFileSize; + // size we actually download (can be smaller than Size if we have partial content) + unsigned long long DownloadSize; + // size of junk content (aka: server error pages) + unsigned long long JunkSize; + // The start of the data (for partial content) unsigned long long StartPos; + time_t Date; bool HaveContent; enum {Chunked,Stream,Closes} Encoding; @@ -75,7 +82,7 @@ struct ServerState bool AddPartialFileToHashes(FileFd &File); bool Comp(URI Other) const {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;}; - virtual void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; Size = 0; JunkSize = 0; + virtual void Reset() {Major = 0; Minor = 0; Result = 0; Code[0] = '\0'; TotalFileSize = 0; JunkSize = 0; StartPos = 0; Encoding = Closes; time(&Date); HaveContent = false; State = Header; Persistent = false; Pipeline = true; MaximumSize = 0;}; virtual bool WriteResponse(std::string const &Data) = 0; |