option forceclose (*) X X X X
-- keyword -------------------------- defaults - frontend - listen -- backend -
option forwardfor X X X X
+option http-buffer-request (*) X X X X
option http-ignore-probes (*) X X X -
option http-keep-alive (*) X X X X
option http-no-delay (*) X X X X
"option forceclose", "option http-keep-alive"
+option http-buffer-request
+no option http-buffer-request
+ Enable or disable waiting for whole HTTP request body before proceeding
+ May be used in sections : defaults | frontend | listen | backend
+ yes | yes | yes | yes
+ Arguments : none
+
+ It is sometimes desirable to wait for the body of an HTTP request before
+ taking a decision. This is what is being done by "balance url_param" for
+ example. The first use case is to buffer requests from slow clients before
+ connecting to the server. Another use case consists in taking the routing
+ decision based on the request body's contents. This option placed in a
+ frontend or backend forces the HTTP processing to wait until either the whole
+ body is received, or the request buffer is full, or the first chunk is
+ complete in case of chunked encoding. It can have undesired side effects with
+ some applications abusing HTTP by expecting unbufferred transmissions between
+ the frontend and the backend, so this should definitely not be used by
+ default.
+
+ See also : "option http-no-delay"
+
+
option http-ignore-probes
no option http-ignore-probes
Enable or disable logging of null connections and request timeouts
usage and CPU usage, which may significantly lower performance in high
latency environments.
+ See also : "option http-buffer-request"
+
option http-pretend-keepalive
no option http-pretend-keepalive
#define PR_O_FWDFOR 0x00000100 /* conditionally insert x-forwarded-for with client address */
#define PR_O_IGNORE_PRB 0x00000200 /* ignore empty requests (aborts and timeouts) */
#define PR_O_NULLNOLOG 0x00000400 /* a connect without request will not be logged */
-/* unused: 0x0800, 0x1000 */
+#define PR_O_WREQ_BODY 0x00000800 /* always wait for the HTTP request body */
+/* unused: 0x1000 */
#define PR_O_FF_ALWAYS 0x00002000 /* always set x-forwarded-for */
#define PR_O_PERSIST 0x00004000 /* server persistence stays effective even when server is down */
#define PR_O_LOGASAP 0x00008000 /* log as soon as possible, without waiting for the stream to complete */
{ "contstats", PR_O_CONTSTATS, PR_CAP_FE, 0, 0 },
{ "dontlognull", PR_O_NULLNOLOG, PR_CAP_FE, 0, 0 },
{ "http_proxy", PR_O_HTTP_PROXY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
+ { "http-buffer-request", PR_O_WREQ_BODY, PR_CAP_FE | PR_CAP_BE, 0, PR_MODE_HTTP },
{ "http-ignore-probes", PR_O_IGNORE_PRB, PR_CAP_FE, 0, PR_MODE_HTTP },
{ "prefer-last-server", PR_O_PREF_LAST, PR_CAP_BE, 0, PR_MODE_HTTP },
{ "logasap", PR_O_LOGASAP, PR_CAP_FE, 0, 0 },
((sess->fe->options & PR_O_HTTP_MODE) != (s->be->options & PR_O_HTTP_MODE)))
http_adjust_conn_mode(s, txn, msg);
+ /* we may have to wait for the request's body */
+ if ((s->be->options & PR_O_WREQ_BODY) &&
+ (msg->body_len || (msg->flags & HTTP_MSGF_TE_CHNK)))
+ req->analysers |= AN_REQ_HTTP_BODY;
+
/* end of job, return OK */
req->analysers &= ~an_bit;
req->analyse_exp = TICK_ETERNITY;
}
/* Was the status page requested with a POST ? */
- if (unlikely(txn->meth == HTTP_METH_POST && txn->req.body_len > 0)) {
+ if (unlikely(txn->meth == HTTP_METH_POST && txn->req.body_len > 0 && msg->msg_state < HTTP_MSG_BODY)) {
if (appctx->ctx.stats.flags & STAT_ADMIN) {
/* we'll need the request body, possibly after sending 100-continue */
req->analysers |= AN_REQ_HTTP_BODY;
if (be->options2 & PR_O2_INDEPSTR)
s->si[1].flags |= SI_FL_INDEP_STR;
+ /* We want to enable the backend-specific analysers except those which
+ * were already run as part of the frontend/listener. Note that it would
+ * be more reliable to store the list of analysers that have been run,
+ * but what we do here is OK for now.
+ */
+ s->req.analysers |= be->be_req_ana & ~strm_li(s)->analysers;
+
/* If the target backend requires HTTP processing, we have to allocate
* the HTTP transaction and hdr_idx if we did not have one.
*/
if (be->mode == PR_MODE_HTTP &&
(be->lbprm.algo & (BE_LB_KIND | BE_LB_PARM)) == (BE_LB_KIND_HI | BE_LB_HASH_PRM))
s->txn->req.flags |= HTTP_MSGF_WAIT_CONN;
+
+ /* we may request to parse a request body */
+ if ((be->options & PR_O_WREQ_BODY) &&
+ (s->txn->req.body_len || (s->txn->req.flags & HTTP_MSGF_TE_CHNK)))
+ s->req.analysers |= AN_REQ_HTTP_BODY;
}
s->flags |= SF_BE_ASSIGNED;
s->res.flags |= CF_NEVER_WAIT;
}
- /* We want to enable the backend-specific analysers except those which
- * were already run as part of the frontend/listener. Note that it would
- * be more reliable to store the list of analysers that have been run,
- * but what we do here is OK for now.
- */
- s->req.analysers |= be->be_req_ana & ~strm_li(s)->analysers;
-
return 1;
}