diff options
| author | David Kalnischkies <david@kalnischkies.de> | 2021-09-16 19:48:33 +0200 |
|---|---|---|
| committer | David Kalnischkies <david@kalnischkies.de> | 2021-09-16 22:40:00 +0200 |
| commit | d013f8957c0d464e0059cc107ca79d887cf9f8aa (patch) | |
| tree | 7324a6308bdbc1034cba26459c2204111b7f7510 /methods | |
| parent | 61c1d7d3658fdcd4b32f8b071cef7941120f8abc (diff) | |
Disable HTTP Range usage if varnish < 6.4 is involved
Debian buster (oldstable) ships 6.1 while bullseye (stable) ships 6.5
and so the later is 'fixed'. Upstream declares 6.0 still as supported.
It might be still a while we encounter "bad" versions in the wild, so
if we can detect and work around the issue at runtime automatically we
can save some users from running into "persistent" partial files.
References: https://varnish-cache.org/docs/6.4/whats-new/changes-6.4.html#changes-in-behavior
Diffstat (limited to 'methods')
| -rw-r--r-- | methods/basehttp.cc | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/methods/basehttp.cc b/methods/basehttp.cc index 396b33999..df34698cd 100644 --- a/methods/basehttp.cc +++ b/methods/basehttp.cc @@ -11,6 +11,7 @@ #include <config.h> #include <apt-pkg/configuration.h> +#include <apt-pkg/debversion.h> #include <apt-pkg/error.h> #include <apt-pkg/fileutl.h> #include <apt-pkg/strutl.h> @@ -19,6 +20,7 @@ #include <limits> #include <map> #include <string> +#include <string_view> #include <vector> #include <ctype.h> #include <signal.h> @@ -255,6 +257,24 @@ bool RequestState::HeaderLine(string const &Line) /*{{{*/ return true; } + if (Server->RangesAllowed && stringcasecmp(Tag, "Via:") == 0) + { + auto const parts = VectorizeString(Val, ' '); + std::string_view const varnish{"(Varnish/"}; + if (parts.size() != 3 || parts[1] != "varnish" || parts[2].empty() || + not APT::String::Startswith(parts[2], std::string{varnish}) || + parts[2].back() != ')') + return true; + auto const version = parts[2].substr(varnish.length(), parts[2].length() - (varnish.length() + 1)); + if (version.empty()) + return true; + std::string_view const varnishsupport{"6.4~"}; + if (debVersioningSystem::CmpFragment(version.data(), version.data() + version.length(), + varnishsupport.begin(), varnishsupport.end()) < 0) + Server->RangesAllowed = false; + return true; + } + return true; } /*}}}*/ @@ -410,6 +430,13 @@ BaseHttpMethod::DealWithHeaders(FetchResult &Res, RequestState &Req) } /* else pass through for error message */ } + // the server is not supporting ranges as much as we would like. Retry without ranges + else if (not Server->RangesAllowed && (Req.Result == 416 || Req.Result == 206)) + { + RemoveFile("server", Queue->DestFile); + NextURI = Queue->Uri; + return TRY_AGAIN_OR_REDIRECT; + } // retry after an invalid range response without partial data else if (Req.Result == 416) { |
