diff options
| author | Julian Andres Klode <jak@debian.org> | 2024-11-18 13:52:58 +0000 |
|---|---|---|
| committer | Julian Andres Klode <jak@debian.org> | 2024-11-18 13:52:58 +0000 |
| commit | 39de3df0774dce8f858cbce384ac63d50c632f5f (patch) | |
| tree | 93b78b07910e9c072ef6f2b65f361de20da4a4d8 /methods | |
| parent | db57773a96d1108bdad78ff3d1359a88d9689912 (diff) | |
| parent | cabcaf3c326408bf71a9a83f51973214fddcefb1 (diff) | |
Merge branch 'fm/apt-rate-limit' into 'main'
http: use Retry-After HTTP header to optimize retries
See merge request apt-team/apt!383
Diffstat (limited to 'methods')
| -rw-r--r-- | methods/basehttp.cc | 29 | ||||
| -rw-r--r-- | methods/basehttp.h | 1 |
2 files changed, 29 insertions, 1 deletions
diff --git a/methods/basehttp.cc b/methods/basehttp.cc index 26b633cba..d335e6fa0 100644 --- a/methods/basehttp.cc +++ b/methods/basehttp.cc @@ -263,6 +263,21 @@ bool RequestState::HeaderLine(string const &Line) /*{{{*/ return true; } + if (stringcasecmp(Tag, "Retry-After:") == 0) + { + unsigned long _retry_after_s; + if (RFC1123StrToTime(Val, RetryAfter)) + { + return true; + } + if (StrToNum(Val.c_str(), _retry_after_s, 4, 10) == 1) + { + RetryAfter = time(nullptr) + _retry_after_s; + return true; + } + return _error->Error(_("Unknown date format")); + } + if (Server->RangesAllowed && stringcasecmp(Tag, "Via:") == 0) { auto const parts = VectorizeString(Val, ' '); @@ -884,7 +899,19 @@ int BaseHttpMethod::Loop() 599, // Network Connect Timeout Error }; if (std::find(std::begin(TransientCodes), std::end(TransientCodes), Req.Result) != std::end(TransientCodes)) - Fail(true); + { + if (Req.RetryAfter) + { + std::unordered_map<std::string, std::string> fields; + fields["Retry-After"] = std::to_string(Req.RetryAfter); + SetFailReason("TooManyRequests"); + FailWithContext(std::string("TooManyRequests"), true, fields); + } + else + { + Fail(true); + } + } else Fail(); break; diff --git a/methods/basehttp.h b/methods/basehttp.h index 080ea527e..c077ea384 100644 --- a/methods/basehttp.h +++ b/methods/basehttp.h @@ -57,6 +57,7 @@ struct RequestState enum {Chunked,Stream,Closes} Encoding = Closes; enum {Header, Data} State = Header; std::string Location; + time_t RetryAfter = 0; FileFd File; |
