#define HTTP_MSGF_XFER_LEN 0x00000004 /* message xfer size can be determined */
#define HTTP_MSGF_VER_11 0x00000008 /* the message is HTTP/1.1 or above */
+/* If this flag is set, we don't process the body until the connect() is confirmed.
+ * This is only used by the request forwarding function to protect the buffer
+ * contents if something needs them during a redispatch.
+ */
+#define HTTP_MSGF_WAIT_CONN 0x00000010 /* Wait for connect() to be confirmed before processing body */
/* Redirect flags */
return 1;
}
- /* in most states, we should abort in case of early close */
- channel_auto_close(req);
+ /* Some post-connect processing might want us to refrain from starting to
+ * forward data. Currently, the only reason for this is "balance url_param"
+ * whichs need to parse/process the request after we've enabled forwarding.
+ */
+ if (unlikely(msg->flags & HTTP_MSGF_WAIT_CONN)) {
+ if (!(s->rep->flags & CF_READ_ATTACHED)) {
+ channel_auto_connect(req);
+ goto missing_data;
+ }
+ msg->flags &= ~HTTP_MSGF_WAIT_CONN;
+ }
/* Note that we don't have to send 100-continue back because we don't
* need the data to complete our job, and it's up to the server to
msg->msg_state = HTTP_MSG_DATA;
}
+ /* in most states, we should abort in case of early close */
+ channel_auto_close(req);
+
while (1) {
unsigned int bytes;
hdr_idx_init(&s->txn.hdr_idx);
}
+ /* If an LB algorithm needs to access some pre-parsed body contents,
+ * we must not start to forward anything until the connection is
+ * confirmed otherwise we'll lose the pointer to these data and
+ * prevent the hash from being doable again after a redispatch.
+ */
+ 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;
+
if (be->options2 & PR_O2_NODELAY) {
s->req->flags |= CF_NEVER_WAIT;
s->rep->flags |= CF_NEVER_WAIT;