summaryrefslogtreecommitdiff
path: root/methods
diff options
context:
space:
mode:
authorMichael Vogt <mvo@ubuntu.com>2015-05-22 17:01:03 +0200
committerMichael Vogt <mvo@ubuntu.com>2015-05-22 17:01:03 +0200
commit4fc6b7570c3e97b65c118b58cdf6729fa94c9b03 (patch)
treef952bb728b9c23f1eebc8f1a87f527ed7c9b0b36 /methods
parent6bf93605fdb8e858d3f0a79a124c1d39f760094d (diff)
parent65759e00eff0513c34f584b99420b72fe0e5073e (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.cc2
-rw-r--r--methods/https.cc8
-rw-r--r--methods/server.cc38
-rw-r--r--methods/server.h13
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;