|
|
@@ -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);
|