When this happens, it is possible to use "option forceclose". It will
actively close the outgoing server channel as soon as the server has finished
- to respond. This option implicitly enables the "httpclose" option.
+ to respond. This option implicitly enables the "httpclose" option. Note that
+ this option also enables the parsing of the full request and response, which
+ means we can close the connection to the server very quickly, releasing some
+ resources earlier than with httpclose.
If this option has been enabled in a "defaults" section, it can be disabled
in a specific instance by prepending the "no" keyword before it.
This option may be set both in a frontend and in a backend. It is enabled if
at least one of the frontend or backend holding a connection has it enabled.
- It is worth noting that "option forceclose" has precedence over "httpclose",
- which itself has precedence over "option http-server-close".
+ It is worth noting that "option forceclose" has precedence over "option
+ http-server-close" and that combining "http-server-close" with "httpclose"
+ basically achieve the same result as "forceclose".
If this option has been enabled in a "defaults" section, it can be disabled
in a specific instance by prepending the "no" keyword before it.
be removed.
It seldom happens that some servers incorrectly ignore this header and do not
- close the connection eventough they reply "Connection: close". For this
- reason, they are not compatible with older HTTP 1.0 browsers. If this
- happens it is possible to use the "option forceclose" which actively closes
- the request connection once the server responds.
+ close the connection eventhough they reply "Connection: close". For this
+ reason, they are not compatible with older HTTP 1.0 browsers. If this happens
+ it is possible to use the "option forceclose" which actively closes the
+ request connection once the server responds. Option "forceclose" also
+ releases the server connection earlier because it does not have to wait for
+ the client to acknowledge it.
This option may be set both in a frontend and in a backend. It is enabled if
at least one of the frontend or backend holding a connection has it enabled.
If "option forceclose" is specified too, it has precedence over "httpclose".
+ If "option http-server-close" is enabled at the same time as "httpclose", it
+ basically achieves the same result as "option forceclose".
If this option has been enabled in a "defaults" section, it can be disabled
in a specific instance by prepending the "no" keyword before it.
* it, so that it can be enforced later.
*/
- if (txn->flags & TX_REQ_VER_11) { /* HTTP/1.1 */
+ if (conn_cl && conn_ka) {
+ txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
+ }
+ else if (txn->flags & TX_REQ_VER_11) { /* HTTP/1.1 */
if (conn_cl) {
- txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
- if (!conn_ka)
- txn->flags |= TX_REQ_CONN_CLO;
+ txn->flags |= TX_REQ_CONN_CLO;
+ if ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN)
+ txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
}
} else { /* HTTP/1.0 */
- if (!conn_ka)
- txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO | TX_REQ_CONN_CLO;
- else if (conn_cl)
- txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
+ if (!conn_ka) {
+ txn->flags |= TX_REQ_CONN_CLO;
+ if ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN)
+ txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
+ }
}
txn->flags |= TX_CON_HDR_PARS;
}
/* Until set to anything else, the connection mode is set as TUNNEL. It will
* only change if both the request and the config reference something else.
+ * Option httpclose by itself does not set a mode, it remains a tunnel mode
+ * in which headers are mangled. However, if another mode is set, it will
+ * affect it (eg: server-close/keep-alive + httpclose = close).
*/
if ((txn->meth != HTTP_METH_CONNECT) &&
tmp = TX_CON_WANT_KAL;
if ((s->fe->options|s->be->options) & PR_O_SERVER_CLO)
tmp = TX_CON_WANT_SCL;
- if ((s->fe->options|s->be->options) & (PR_O_HTTP_CLOSE|PR_O_FORCE_CLO))
- tmp = TX_CON_WANT_CLO;
-
- if (!(txn->flags & TX_REQ_XFER_LEN))
+ if ((s->fe->options|s->be->options) & PR_O_FORCE_CLO)
tmp = TX_CON_WANT_CLO;
if (!(txn->flags & TX_CON_HDR_PARS))
if ((txn->flags & TX_CON_WANT_MSK) < tmp)
txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | tmp;
+
+ if ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) {
+ if ((s->fe->options|s->be->options) & PR_O_HTTP_CLOSE)
+ txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
+ if (!(txn->flags & TX_REQ_XFER_LEN))
+ txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
+ }
}
/* We're really certain of the connection mode (tunnel, close, keep-alive)
* Connection header exists. Note that a CONNECT method will not enter
* here.
*/
- if (!(txn->flags & TX_REQ_CONN_CLO) && ((txn->flags & TX_CON_WANT_MSK) >= TX_CON_WANT_SCL)) {
+ if (!(txn->flags & TX_REQ_CONN_CLO) &&
+ ((txn->flags & TX_CON_WANT_MSK) >= TX_CON_WANT_SCL ||
+ ((s->fe->options|s->be->options) & PR_O_HTTP_CLOSE))) {
char *cur_ptr, *cur_end, *cur_next;
int old_idx, delta, val;
int must_delete;
}
/* 11: add "Connection: close" if needed and not yet set. */
- if (!(txn->flags & TX_REQ_CONN_CLO) && ((txn->flags & TX_CON_WANT_MSK) >= TX_CON_WANT_SCL)) {
+ if (!(txn->flags & TX_REQ_CONN_CLO) &&
+ ((txn->flags & TX_CON_WANT_MSK) >= TX_CON_WANT_SCL ||
+ ((s->fe->options|s->be->options) & PR_O_HTTP_CLOSE))) {
if (unlikely(http_header_add_tail2(req, &txn->req, &txn->hdr_idx,
"Connection: close", 17) < 0))
goto return_bad_req;
buffer_shutw_now(buf);
buf->cons->flags |= SI_FL_NOLINGER;
}
- else if ((s->fe->options | s->be->options) & PR_O_FORCE_CLO) {
+ else if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_CLO) {
/* Option forceclose is set, let's enforce it now
* that we're not expecting any new data to come.
*/
*/
if ((txn->meth != HTTP_METH_CONNECT) &&
- (txn->status >= 200) &&
- (txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN &&
- !(txn->flags & TX_CON_HDR_PARS)) {
+ (txn->status >= 200) && !(txn->flags & TX_CON_HDR_PARS) &&
+ ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN ||
+ ((t->fe->options|t->be->options) & PR_O_HTTP_CLOSE))) {
int may_keep = 0, may_close = 0; /* how it may be understood */
struct hdr_ctx ctx;
* handled. We also explicitly state that we will close in
* case of an ambiguous response having no content-length.
*/
- if ((may_close &&
+ if ((may_close && ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) &&
(may_keep || ((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_SCL))) ||
!(txn->flags & TX_RES_XFER_LEN))
txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_CLO;
/* Now we must adjust the response header :
- * - set "close" if may_keep and WANT_CLO
+ * - set "close" if may_keep and (WANT_CLO | httpclose)
* - remove "close" if WANT_SCL and REQ_1.1 and may_close and (content-length or TE_CHNK)
* - add "keep-alive" if WANT_SCL and REQ_1.0 and may_close and content-length
- *
- * Until we support the server-close mode, we'll only support the set "close".
*/
- if (may_keep && (txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_CLO)
+ if (may_keep &&
+ ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_CLO ||
+ ((t->fe->options|t->be->options) & PR_O_HTTP_CLOSE)))
must_close = 1;
else if (((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL) &&
may_close && (txn->flags & TX_RES_XFER_LEN)) {