From ac886bea59fe3e8b9b136f2a650b43dafae6a1b3 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Thu, 15 Sep 2022 13:57:27 +0200 Subject: use http header 'Cache-Control: no-cache' for soft failure This is standard header... --- README.md | 13 ++--- pacredir.c | 2 +- ...r-Cache-Control-no-cache-for-soft-failure.patch | 58 ++++++++++++++++++++++ ...tp-header-to-indicate-an-expected-failure.patch | 43 ---------------- 4 files changed, 66 insertions(+), 50 deletions(-) create mode 100644 patches/0001-support-http-header-Cache-Control-no-cache-for-soft-failure.patch delete mode 100644 patches/0001-support-http-header-to-indicate-an-expected-failure.patch diff --git a/README.md b/README.md index ff1091a..44c4182 100644 --- a/README.md +++ b/README.md @@ -99,16 +99,17 @@ This is the simplest workaround - just disable the server error limit. We can agree this is not to be desired - in general the feature is reasonable. -### Support http header to indicate an expected failure +### Support http header to indicate a soft failure This solution is simple, yet powerful: -[Support http header to indicate an expected failure](patches/0001-support-http-header-to-indicate-an-expected-failure.patch) +[Support http header 'Cache-Control: no-cache' for soft failure](patches/0001-support-http-header-Cache-Control-no-cache-for-soft-failure.patch) -By setting an extra HTTP header `X-Pacman-Expected-Failure` the server can -indicate that the failure is expected. The next server is tried without -error message and without increasing the server's error count. +By setting the HTTP header `Cache-Control: no-cache` when returning with +the status code `404` (not found) the server can indicate that this is a +soft failure. No error message is shown, and server's error count is +not increased. -Sadly upstream denied. 😢 +Sadly upstream denied. 😢 (At least an earlier version of the patch...) ### Implement CacheServer diff --git a/pacredir.c b/pacredir.c index 0366888..c5cc23f 100644 --- a/pacredir.c +++ b/pacredir.c @@ -578,7 +578,7 @@ response: page = malloc(strlen(PAGE404) + strlen(basename) + 1); sprintf(page, PAGE404, basename); response = MHD_create_response_from_buffer(strlen(page), (void*) page, MHD_RESPMEM_MUST_FREE); - ret = MHD_add_response_header(response, "X-Pacman-Expected-Failure", "true"); + ret = MHD_add_response_header(response, "Cache-Control", "no-cache"); ret = MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response); } diff --git a/patches/0001-support-http-header-Cache-Control-no-cache-for-soft-failure.patch b/patches/0001-support-http-header-Cache-Control-no-cache-for-soft-failure.patch new file mode 100644 index 0000000..c81432a --- /dev/null +++ b/patches/0001-support-http-header-Cache-Control-no-cache-for-soft-failure.patch @@ -0,0 +1,58 @@ +From 1288a202b61cf01fbff8a8bd0071e57383aa954e Mon Sep 17 00:00:00 2001 +From: Christian Hesse +Date: Fri, 21 May 2021 09:52:34 +0200 +Subject: [PATCH 1/1] support http header 'Cache-Control: no-cache' for soft + failure + +By setting the HTTP header 'Cache-Control: no-cache' when returning with +the status code 404 (not found) the server can indicate that this is a +soft failure. No error message is shown, and server's error count is +not increased. + +This can be used by servers that are not expected to be complete, for +example when serving a local cache [0]. In nginx this can be achived by +adding a single directive in location block: + + add_header Cache-Control "no-cache"; + +Also this is a perfect match for pacredir [1]. + +[0] https://wiki.archlinux.org/title/Pacman/Tips_and_tricks#Network_shared_pacman_cache +[1] https://git.eworm.de/cgit/pacredir/about/ + +Signed-off-by: Christian Hesse +--- + lib/libalpm/dload.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c +index 4fa17b35..23034584 100644 +--- a/lib/libalpm/dload.c ++++ b/lib/libalpm/dload.c +@@ -274,8 +274,10 @@ static size_t dload_parseheader_cb(void *ptr, size_t size, size_t nmemb, void *u + { + size_t realsize = size * nmemb; + const char *fptr, *endptr = NULL; ++ const char * const cc_header = "Cache-Control:"; + const char * const cd_header = "Content-Disposition:"; + const char * const fn_key = "filename="; ++ const char * const nc_key = "no-cache"; + struct dload_payload *payload = (struct dload_payload *)user; + long respcode; + +@@ -302,6 +304,15 @@ static size_t dload_parseheader_cb(void *ptr, size_t size, size_t nmemb, void *u + } + } + ++ /* By setting the HTTP header 'Cache-Control: no-cache' the server can indicate ++ that this is a soft failure which should not be cached. No error message is ++ shown, and server's error count is not increased. */ ++ if(_alpm_raw_ncmp(cc_header, ptr, strlen(cc_header)) == 0) { ++ if(strstr(ptr, nc_key)) { ++ payload->errors_ok = 1; ++ } ++ } ++ + curl_easy_getinfo(payload->curl, CURLINFO_RESPONSE_CODE, &respcode); + if(payload->respcode != respcode) { + payload->respcode = respcode; diff --git a/patches/0001-support-http-header-to-indicate-an-expected-failure.patch b/patches/0001-support-http-header-to-indicate-an-expected-failure.patch deleted file mode 100644 index 6bc977a..0000000 --- a/patches/0001-support-http-header-to-indicate-an-expected-failure.patch +++ /dev/null @@ -1,43 +0,0 @@ -From b50863ad56c3c972e4bfbc9108523fee267d63fa Mon Sep 17 00:00:00 2001 -From: Christian Hesse -Date: Fri, 21 May 2021 09:52:34 +0200 -Subject: [PATCH] support http header to indicate an expected failure - -By setting an extra HTTP header 'X-Pacman-Expected-Failure' the server can -indicate that the failure is expected. The next server is tried without -error message and without increasing the server's error count. - -This can be used by servers that are not expected to be complete, for -example when serving a local cache. - -Signed-off-by: Christian Hesse ---- - lib/libalpm/dload.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c -index 7c27c3ea..d39125ca 100644 ---- a/lib/libalpm/dload.c -+++ b/lib/libalpm/dload.c -@@ -277,6 +277,7 @@ static size_t dload_parseheader_cb(void *ptr, size_t size, size_t nmemb, void *u - const char *fptr, *endptr = NULL; - const char * const cd_header = "Content-Disposition:"; - const char * const fn_key = "filename="; -+ const char * const xpef_header = "X-Pacman-Expected-Failure:"; - struct dload_payload *payload = (struct dload_payload *)user; - long respcode; - -@@ -303,6 +304,13 @@ static size_t dload_parseheader_cb(void *ptr, size_t size, size_t nmemb, void *u - } - } - -+ /* By setting an extra HTTP header 'X-Pacman-Expected-Failure' the server can -+ indicate that the failure is expected. The next server is tried without -+ error message and without increasing the server's error count. */ -+ if(_alpm_raw_ncmp(xpef_header, ptr, strlen(xpef_header)) == 0) { -+ payload->errors_ok = 1; -+ } -+ - curl_easy_getinfo(payload->curl, CURLINFO_RESPONSE_CODE, &respcode); - if(payload->respcode != respcode) { - payload->respcode = respcode; -- cgit v1.2.3-54-g00ecf