summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2021-10-18 13:42:56 +0000
committerJulian Andres Klode <jak@debian.org>2021-10-18 13:42:56 +0000
commitad7bae309a827592aa228af9470c1aa7abdd189e (patch)
treeb62356022ed89241636500fafa7105429c095651
parentefa3528de4277a3d5195c5ce875e7ee960726239 (diff)
parentfe4201380bd377aebd25bd96a06a7eda6c74a533 (diff)
Merge branch 'pu/content-length-0' into 'main'
basehttp: Turn HaveContent into a TriState See merge request apt-team/apt!179
-rw-r--r--methods/basehttp.cc34
-rw-r--r--methods/basehttp.h9
2 files changed, 28 insertions, 15 deletions
diff --git a/methods/basehttp.cc b/methods/basehttp.cc
index df34698cd..617a8f5d5 100644
--- a/methods/basehttp.cc
+++ b/methods/basehttp.cc
@@ -76,7 +76,7 @@ ServerState::RunHeadersResult ServerState::RunHeaders(RequestState &Req,
continue;
// Tidy up the connection persistence state.
- if (Req.Encoding == RequestState::Closes && Req.HaveContent == true)
+ if (Req.Encoding == RequestState::Closes && Req.haveContent == HaveContent::TRUE)
Persistent = false;
return RUN_HEADERS_OK;
@@ -156,10 +156,13 @@ bool RequestState::HeaderLine(string const &Line) /*{{{*/
{
auto ContentLength = strtoull(Val.c_str(), NULL, 10);
if (ContentLength == 0)
+ {
+ haveContent = HaveContent::FALSE;
return true;
+ }
if (Encoding == Closes)
Encoding = Stream;
- HaveContent = true;
+ haveContent = HaveContent::TRUE;
unsigned long long * DownloadSizePtr = &DownloadSize;
if (Result == 416 || (Result >= 300 && Result < 400))
@@ -169,7 +172,7 @@ bool RequestState::HeaderLine(string const &Line) /*{{{*/
if (*DownloadSizePtr >= std::numeric_limits<unsigned long long>::max())
return _error->Errno("HeaderLine", _("The HTTP server sent an invalid Content-Length header"));
else if (*DownloadSizePtr == 0)
- HaveContent = false;
+ haveContent = 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
@@ -182,7 +185,8 @@ bool RequestState::HeaderLine(string const &Line) /*{{{*/
if (stringcasecmp(Tag,"Content-Type:") == 0)
{
- HaveContent = true;
+ if (haveContent == HaveContent::UNKNOWN)
+ haveContent = HaveContent::TRUE;
return true;
}
@@ -192,7 +196,8 @@ bool RequestState::HeaderLine(string const &Line) /*{{{*/
// for such responses.
if ((Result == 416 || Result == 206) && stringcasecmp(Tag,"Content-Range:") == 0)
{
- HaveContent = true;
+ if (haveContent == HaveContent::UNKNOWN)
+ haveContent = 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",&TotalFileSize) == 1)
@@ -209,7 +214,8 @@ bool RequestState::HeaderLine(string const &Line) /*{{{*/
if (stringcasecmp(Tag,"Transfer-Encoding:") == 0)
{
- HaveContent = true;
+ if (haveContent == HaveContent::UNKNOWN)
+ haveContent = HaveContent::TRUE;
if (stringcasecmp(Val,"chunked") == 0)
Encoding = Chunked;
return true;
@@ -356,7 +362,7 @@ BaseHttpMethod::DealWithHeaders(FetchResult &Res, RequestState &Req)
{
SetFailReason("RedirectionLoop");
_error->Error("Redirection loop encountered");
- if (Req.HaveContent == true)
+ if (Req.haveContent == HaveContent::TRUE)
return ERROR_WITH_CONTENT_PAGE;
return ERROR_UNRECOVERABLE;
}
@@ -373,7 +379,7 @@ BaseHttpMethod::DealWithHeaders(FetchResult &Res, RequestState &Req)
if (tmpURI.Access.find('+') != std::string::npos)
{
_error->Error("Server tried to trick us into using a specific implementation: %s", tmpURI.Access.c_str());
- if (Req.HaveContent == true)
+ if (Req.haveContent == HaveContent::TRUE)
return ERROR_WITH_CONTENT_PAGE;
return ERROR_UNRECOVERABLE;
}
@@ -399,7 +405,7 @@ BaseHttpMethod::DealWithHeaders(FetchResult &Res, RequestState &Req)
{
SetFailReason("RedirectionLoop");
_error->Error("Redirection loop encountered");
- if (Req.HaveContent == true)
+ if (Req.haveContent == HaveContent::TRUE)
return ERROR_WITH_CONTENT_PAGE;
return ERROR_UNRECOVERABLE;
}
@@ -459,11 +465,11 @@ BaseHttpMethod::DealWithHeaders(FetchResult &Res, RequestState &Req)
if (partialHit == true)
{
// the file is completely downloaded, but was not moved
- if (Req.HaveContent == true)
+ if (Req.haveContent == HaveContent::TRUE)
{
// nuke the sent error page
Server->RunDataToDevNull(Req);
- Req.HaveContent = false;
+ Req.haveContent = HaveContent::FALSE;
}
Req.StartPos = Req.TotalFileSize;
Req.Result = 200;
@@ -487,7 +493,7 @@ BaseHttpMethod::DealWithHeaders(FetchResult &Res, RequestState &Req)
SetFailReason(err);
_error->Error("%u %s", Req.Result, Req.Code);
}
- if (Req.HaveContent == true)
+ if (Req.haveContent == HaveContent::TRUE)
return ERROR_WITH_CONTENT_PAGE;
return ERROR_UNRECOVERABLE;
}
@@ -726,7 +732,7 @@ int BaseHttpMethod::Loop()
// so instead we use the size of the biggest item in the queue
Req.MaximumSize = FindMaximumObjectSizeInQueue();
- if (Req.HaveContent)
+ if (Req.haveContent == HaveContent::TRUE)
{
/* If the server provides Content-Length we can figure out with it if
this satisfies any request we have made so far (in the pipeline).
@@ -888,7 +894,7 @@ int BaseHttpMethod::Loop()
case TRY_AGAIN_OR_REDIRECT:
{
// Clear rest of response if there is content
- if (Req.HaveContent)
+ if (Req.haveContent == HaveContent::TRUE)
Server->RunDataToDevNull(Req);
Redirect(NextURI);
break;
diff --git a/methods/basehttp.h b/methods/basehttp.h
index c0d14d854..2a13c7abf 100644
--- a/methods/basehttp.h
+++ b/methods/basehttp.h
@@ -27,6 +27,12 @@ class Hashes;
class BaseHttpMethod;
struct ServerState;
+enum class HaveContent
+{
+ UNKNOWN,
+ FALSE,
+ TRUE,
+};
struct RequestState
{
unsigned int Major = 0;
@@ -46,7 +52,8 @@ struct RequestState
unsigned long long MaximumSize = 0;
time_t Date;
- bool HaveContent = false;
+ HaveContent haveContent = HaveContent::UNKNOWN;
+
enum {Chunked,Stream,Closes} Encoding = Closes;
enum {Header, Data} State = Header;
std::string Location;