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()
{
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()) {
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