]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
HTTP Compliance: reply with 504 (Gateway Timeout) if required validation fails.
authorAlex Rousskov <rousskov@measurement-factory.com>
Mon, 4 Oct 2010 15:40:04 +0000 (09:40 -0600)
committerAlex Rousskov <rousskov@measurement-factory.com>
Mon, 4 Oct 2010 15:40:04 +0000 (09:40 -0600)
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

src/forward.cc
src/forward.h

index 6f366785f7fbc0de354ee71dbb84b3406b1cf4a5..5cbed32ff573ec0cbef97de85f2d86c7ea7d7b6c 100644 (file)
@@ -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)
 {
index 26214b3a202756afe1b736ebba60be6d0ced00ea..126e021f6b5d42247dfd9f1045c7e2665667d0ee 100644 (file)
@@ -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