Hi Willy,
Following my recent patches on HTTP/1.0 responses without content-length
when compression filter is enabled, here is 2 small patches. The first
one is a small code cleanup and the second one adds handy debug messages.
Thanks,
--
Christopher Faulet
>From c998beb94b02be0f07adc950400c495f60776b91 Mon Sep 17 00:00:00 2001
From: Christopher Faulet <cfau...@haproxy.com>
Date: Thu, 30 Mar 2017 11:21:53 +0200
Subject: [PATCH 1/2] MINOR: http: remove useless check on HTTP_MSGF_XFER_LEN
for the request
X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4
The flag HTTP_MSGF_XFER_LEN is always set for an HTTP request because we always
now the body length. So there is no need to do check on it.
---
src/proto_http.c | 39 +++++++++++++++------------------------
1 file changed, 15 insertions(+), 24 deletions(-)
diff --git a/src/proto_http.c b/src/proto_http.c
index 487c0fc..a00ea78 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -3122,7 +3122,7 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit)
/* set TE_CHNK and XFER_LEN only if "chunked" is seen last */
while (http_find_header2("Transfer-Encoding", 17, req->buf->p, &txn->hdr_idx, &ctx)) {
if (ctx.vlen == 7 && strncasecmp(ctx.line + ctx.val, "chunked", 7) == 0)
- msg->flags |= (HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
+ msg->flags |= HTTP_MSGF_TE_CHNK;
else if (msg->flags & HTTP_MSGF_TE_CHNK) {
/* chunked not last, return badreq */
goto return_bad_req;
@@ -3158,7 +3158,7 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit)
goto return_bad_req; /* already specified, was different */
}
- msg->flags |= HTTP_MSGF_CNT_LEN | HTTP_MSGF_XFER_LEN;
+ msg->flags |= HTTP_MSGF_CNT_LEN;
msg->body_len = msg->chunk_len = cl;
}
@@ -4256,8 +4256,7 @@ static int http_apply_redirect_rule(struct redirect_rule *rule, struct stream *s
/* let's log the request time */
s->logs.tv_request = now;
- if ((req->flags & HTTP_MSGF_XFER_LEN) &&
- ((!(req->flags & HTTP_MSGF_TE_CHNK) && !req->body_len) || (req->msg_state == HTTP_MSG_DONE)) &&
+ if (((!(req->flags & HTTP_MSGF_TE_CHNK) && !req->body_len) || (req->msg_state == HTTP_MSG_DONE)) &&
((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_SCL ||
(txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL)) {
/* keep-alive possible */
@@ -4847,22 +4846,20 @@ int http_process_request(struct stream *s, struct channel *req, int an_bit)
req->analysers |= AN_REQ_HTTP_BODY;
}
- if (msg->flags & HTTP_MSGF_XFER_LEN) {
- req->analysers &= ~AN_REQ_FLT_XFER_DATA;
- req->analysers |= AN_REQ_HTTP_XFER_BODY;
+ req->analysers &= ~AN_REQ_FLT_XFER_DATA;
+ req->analysers |= AN_REQ_HTTP_XFER_BODY;
#ifdef TCP_QUICKACK
- /* We expect some data from the client. Unless we know for sure
- * we already have a full request, we have to re-enable quick-ack
- * in case we previously disabled it, otherwise we might cause
- * the client to delay further data.
- */
- if ((sess->listener->options & LI_O_NOQUICKACK) &&
- cli_conn && conn_ctrl_ready(cli_conn) &&
- ((msg->flags & HTTP_MSGF_TE_CHNK) ||
- (msg->body_len > req->buf->i - txn->req.eoh - 2)))
- setsockopt(cli_conn->t.sock.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
+ /* We expect some data from the client. Unless we know for sure
+ * we already have a full request, we have to re-enable quick-ack
+ * in case we previously disabled it, otherwise we might cause
+ * the client to delay further data.
+ */
+ if ((sess->listener->options & LI_O_NOQUICKACK) &&
+ cli_conn && conn_ctrl_ready(cli_conn) &&
+ ((msg->flags & HTTP_MSGF_TE_CHNK) ||
+ (msg->body_len > req->buf->i - txn->req.eoh - 2)))
+ setsockopt(cli_conn->t.sock.fd, IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
#endif
- }
/*************************************************************
* OK, that's finished for the headers. We have done what we *
@@ -4871,12 +4868,6 @@ int http_process_request(struct stream *s, struct channel *req, int an_bit)
req->analyse_exp = TICK_ETERNITY;
req->analysers &= ~an_bit;
- /* if the server closes the connection, we want to immediately react
- * and close the socket to save packets and syscalls.
- */
- if (!(req->analysers & AN_REQ_HTTP_XFER_BODY))
- s->si[1].flags |= SI_FL_NOHALF;
-
s->logs.tv_request = now;
/* OK let's go on with the BODY now */
return 1;
--
2.9.3
>From 776963e253b229f8e4749d8c4e22bd01dea6c7aa Mon Sep 17 00:00:00 2001
From: Christopher Faulet <cfau...@haproxy.com>
Date: Thu, 30 Mar 2017 11:33:44 +0200
Subject: [PATCH 2/2] MINOR: http: Add debug messages when HTTP body analyzers
are called
X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4
---
src/proto_http.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/src/proto_http.c b/src/proto_http.c
index a00ea78..2d97fbe 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -5630,6 +5630,13 @@ int http_resync_states(struct stream *s)
break;
}
+ DPRINTF(stderr,"[%u] %s: stream=%p old=%d,%d cur=%d,%d\n",
+ now_ms, __FUNCTION__,
+ s,
+ old_req_state, old_res_state,
+ txn->req.msg_state, txn->rsp.msg_state);
+
+
/* OK, both state machines agree on a compatible state.
* There are a few cases we're interested in :
* - HTTP_MSG_TUNNEL on either means we have to disable both analysers
@@ -5716,6 +5723,15 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
struct http_msg *msg = &s->txn->req;
int ret;
+ DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
+ now_ms, __FUNCTION__,
+ s,
+ req,
+ req->rex, req->wex,
+ req->flags,
+ req->buf->i,
+ req->analysers);
+
if (unlikely(msg->msg_state < HTTP_MSG_BODY))
return 0;
@@ -6900,6 +6916,15 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
struct http_msg *msg = &s->txn->rsp;
int ret;
+ DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
+ now_ms, __FUNCTION__,
+ s,
+ res,
+ res->rex, res->wex,
+ res->flags,
+ res->buf->i,
+ res->analysers);
+
if (unlikely(msg->msg_state < HTTP_MSG_BODY))
return 0;
--
2.9.3