From: Alex Rousskov Date: Mon, 4 Oct 2010 15:40:04 +0000 (-0600) Subject: HTTP Compliance: reply with 504 (Gateway Timeout) if required validation fails. X-Git-Tag: take1~205 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2ac4f6b5309a8e196c252b421e4ae1283742680d;p=thirdparty%2Fsquid.git HTTP Compliance: reply with 504 (Gateway Timeout) if required validation fails. RFC 2616 says that we MUST reply with 504 (Gateway Timeout) if validation fails and cached reply has proxy-revalidate, must-revalidate or s-maxage Cache-Control directive. FwdState::makeConnectingError() method is added to set error status depending on whether the request was a validation request. Co-Advisor test cases: test_case/rfc2616/noSrv-hit-must-reval-s-maxage-resp test_case/rfc2616/noSrv-hit-must-reval-proxy-revalidate-resp test_case/rfc2616/noSrv-hit-must-reval-must-revalidate-resp --- diff --git a/src/forward.cc b/src/forward.cc index 6f366785f7..5cbed32ff5 100644 --- a/src/forward.cc +++ b/src/forward.cc @@ -597,7 +597,7 @@ FwdState::negotiateSSL(int fd) debugs(81, 1, "fwdNegotiateSSL: Error negotiating SSL connection on FD " << fd << ": " << ERR_error_string(ERR_get_error(), NULL) << " (" << ssl_error << "/" << ret << "/" << errno << ")"); - ErrorState *anErr = errorCon(ERR_SECURE_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request); + ErrorState *const anErr = makeConnectingError(ERR_SECURE_CONNECT_FAIL); #ifdef EPROTO anErr->xerrno = EPROTO; @@ -717,7 +717,7 @@ FwdState::connectDone(int aServerFD, const DnsLookupDetails &dns, comm_err_t sta debugs(17, 4, "fwdConnectDone: Unknown host: " << request->GetHost()); - ErrorState *anErr = errorCon(ERR_DNS_FAIL, HTTP_SERVICE_UNAVAILABLE, request); + ErrorState *const anErr = makeConnectingError(ERR_DNS_FAIL); anErr->dnsError = dns.error; @@ -726,7 +726,7 @@ FwdState::connectDone(int aServerFD, const DnsLookupDetails &dns, comm_err_t sta comm_close(server_fd); } else if (status != COMM_OK) { assert(fs); - ErrorState *anErr = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request); + ErrorState *const anErr = makeConnectingError(ERR_CONNECT_FAIL); anErr->xerrno = xerrno; fail(anErr); @@ -1164,6 +1164,19 @@ FwdState::reforward() return reforwardableStatus(s); } +/** + * Create "503 Service Unavailable" or "504 Gateway Timeout" error depending + * on whether this is a validation request. RFC 2616 says that we MUST reply + * with "504 Gateway Timeout" if validation fails and cached reply has + * proxy-revalidate, must-revalidate or s-maxage Cache-Control directive. + */ +ErrorState * +FwdState::makeConnectingError(const err_type type) const +{ + return errorCon(type, request->flags.need_validation ? + HTTP_GATEWAY_TIMEOUT : HTTP_SERVICE_UNAVAILABLE, request); +} + static void fwdStats(StoreEntry * s) { diff --git a/src/forward.h b/src/forward.h index 26214b3a20..126e021f6b 100644 --- a/src/forward.h +++ b/src/forward.h @@ -65,6 +65,7 @@ private: void doneWithRetries(); void completed(); void retryOrBail(); + ErrorState *makeConnectingError(const err_type type) const; static void RegisterWithCacheManager(void); #if WIP_FWD_LOG