]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Author: Eduard Bagdasaryan <eduard.bagdasaryan@measurement-factory.com>
authorEduard Bagdasaryan <eduard.bagdasaryan@measurement-factory.com>
Sat, 12 Mar 2016 20:27:35 +0000 (13:27 -0700)
committerAlex Rousskov <rousskov@measurement-factory.com>
Sat, 12 Mar 2016 20:27:35 +0000 (13:27 -0700)
Added ACL-driven server_pconn_for_nonretriable squid.conf directive.

This directive provides fine-grained control over persistent connection
reuse when forwarding HTTP requests that Squid cannot retry. It is
useful in environments where opening new connections is very expensive
and race conditions associated with persistent connections are very rare
and/or only cause minor problems.

src/FwdState.cc
src/SquidConfig.h
src/cf.data.pre

index a4e860dc36cead8c81de17a5aac4d10df9a86028..fa0b3ffae4fe1a70c73713ea7432fc8fac9d1d17 100644 (file)
@@ -589,14 +589,7 @@ FwdState::checkRetry()
     return true;
 }
 
-/*
- * FwdState::checkRetriable
- *
- * Return TRUE if this is the kind of request that can be retried
- * after a failure.  If the request is not retriable then we don't
- * want to risk sending it on a persistent connection.  Instead we'll
- * force it to go on a new HTTP connection.
- */
+/// Whether we may try sending this request again after a failure.
 bool
 FwdState::checkRetriable()
 {
@@ -1188,9 +1181,14 @@ FwdState::pconnPush(Comm::ConnectionPointer &conn, const char *domain)
 Comm::ConnectionPointer
 FwdState::pconnPop(const Comm::ConnectionPointer &dest, const char *domain)
 {
+    bool retriable = checkRetriable();
+    if (!retriable && Config.accessList.serverPconnForNonretriable) {
+        ACLFilledChecklist ch(Config.accessList.serverPconnForNonretriable, request, NULL);
+        retriable = (ch.fastCheck() == ACCESS_ALLOWED);
+    }
     // always call shared pool first because we need to close an idle
     // connection there if we have to use a standby connection.
-    Comm::ConnectionPointer conn = fwdPconnPool->pop(dest, domain, checkRetriable());
+    Comm::ConnectionPointer conn = fwdPconnPool->pop(dest, domain, retriable);
     if (!Comm::IsConnOpen(conn)) {
         // either there was no pconn to pop or this is not a retriable xaction
         if (CachePeer *peer = dest->getPeer()) {
index 0a0689e482f8b76b29084ed44f59f0cd6c0b03de..59ea1cebc40dae3a58adeb1916274c5b1f4872cf 100644 (file)
@@ -394,6 +394,7 @@ public:
         acl_access *ftp_epsv;
 
         acl_access *forceRequestBodyContinuation;
+        acl_access *serverPconnForNonretriable;
     } accessList;
     AclDenyInfoList *denyInfoList;
 
index bd66346231befa3d42674921b864e82a97112d23..430e77e51b159aa83646edbc866108fe9c7588b9 100644 (file)
@@ -9632,4 +9632,42 @@ DOC_START
        that the request body is needed. Delaying is the default behavior.
 DOC_END
 
+NAME: server_pconn_for_nonretriable
+TYPE: acl_access
+DEFAULT: none
+DEFAULT_DOC: Open new connections for forwarding requests Squid cannot retry safely.
+LOC: Config.accessList.serverPconnForNonretriable
+DOC_START
+       This option provides fine-grained control over persistent connection
+       reuse when forwarding HTTP requests that Squid cannot retry. It is useful
+       in environments where opening new connections is very expensive
+       (e.g., all connections are secured with TLS with complex client and server
+       certificate validation) and race conditions associated with persistent
+       connections are very rare and/or only cause minor problems.
+
+       HTTP prohibits retrying unsafe and non-idempotent requests (e.g., POST).
+       Squid limitations also prohibit retrying all requests with bodies (e.g., PUT).
+       By default, when forwarding such "risky" requests, Squid opens a new
+       connection to the server or cache_peer, even if there is an idle persistent
+       connection available. When Squid is configured to risk sending a non-retriable
+       request on a previously used persistent connection, and the server closes
+       the connection before seeing that risky request, the user gets an error response
+       from Squid. In most cases, that error response will be HTTP 502 (Bad Gateway)
+       with ERR_ZERO_SIZE_OBJECT or ERR_WRITE_ERROR (peer connection reset) error detail.
+
+       If an allow rule matches, Squid reuses an available idle persistent connection
+       (if any) for the request that Squid cannot retry. If a deny rule matches, then
+       Squid opens a new connection for the request that Squid cannot retry.
+
+       This option does not affect requests that Squid can retry. They will reuse idle
+       persistent connections (if any).
+
+       This clause only supports fast acl types.
+       See http://wiki.squid-cache.org/SquidFaq/SquidAcl for details.
+
+       Example:
+               acl SpeedIsWorthTheRisk method POST
+               server_pconn_for_nonretriable allow SpeedIsWorthTheRisk
+DOC_END
+
 EOF