From: Willy Tarreau Date: Thu, 17 Apr 2014 22:53:43 +0000 (+0200) Subject: MEDIUM: http: cleanup: centralize a little bit HTTP compression end X-Git-Tag: v1.5-dev23~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=168ebc5e2bfe7686e25bb0a95b19f19846c0c483;p=thirdparty%2Fhaproxy.git MEDIUM: http: cleanup: centralize a little bit HTTP compression end The call to flush the compression buffers only needs to be done when entering the final states or when leaving with missing data. After that, if trailers are present, they have to be forwarded. --- diff --git a/src/proto_http.c b/src/proto_http.c index 52428265c1..ac7fe01ff5 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -6207,7 +6207,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi } } - if (s->comp_algo != NULL) { + if (s->comp_algo != NULL && msg->msg_state < HTTP_MSG_TRAILERS) { ret = http_compression_buffer_init(s, res->buf, tmpbuf); /* init a buffer with headers */ if (ret < 0) { res->flags |= CF_WAKE_WRITE; @@ -6247,10 +6247,6 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi msg->msg_state = HTTP_MSG_CHUNK_CRLF; } else { msg->msg_state = HTTP_MSG_DONE; - if (compressing) { - http_compression_buffer_end(s, &res->buf, &tmpbuf, 1); - compressing = 0; - } break; } /* fall through for HTTP_MSG_CHUNK_CRLF */ @@ -6282,14 +6278,16 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi http_capture_bad_message(&s->be->invalid_rep, s, msg, HTTP_MSG_CHUNK_SIZE, s->fe); goto return_bad_res; } - if (compressing && msg->msg_state == HTTP_MSG_TRAILERS) { - http_compression_buffer_end(s, &res->buf, &tmpbuf, 1); - compressing = 0; - } /* otherwise we're in HTTP_MSG_DATA or HTTP_MSG_TRAILERS state */ break; case HTTP_MSG_TRAILERS - HTTP_MSG_DATA: + if (unlikely(compressing)) { + /* we need to flush output contents before syncing FSMs */ + http_compression_buffer_end(s, &res->buf, &tmpbuf, 1); + compressing = 0; + } + ret = http_forward_trailers(msg); if (ret == 0) goto missing_data; @@ -6298,19 +6296,20 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi http_capture_bad_message(&s->be->invalid_rep, s, msg, HTTP_MSG_TRAILERS, s->fe); goto return_bad_res; } - if (s->comp_algo != NULL) { - /* forwarding trailers */ - channel_forward(res, msg->next); - msg->next = 0; - msg->sov = 0; - } - /* we're in HTTP_MSG_DONE now, but we might still have - * some data pending, so let's loop over once. - */ - break; + /* forwarding trailers */ + channel_forward(res, msg->next); + msg->next = 0; + msg->sov = 0; + + /* we're in HTTP_MSG_DONE now, fall through */ default: /* other states, DONE...TUNNEL */ + if (unlikely(compressing)) { + /* we need to flush output contents before syncing FSMs */ + http_compression_buffer_end(s, &res->buf, &tmpbuf, 1); + compressing = 0; + } ret = msg->msg_state; /* for keep-alive we don't want to forward closes on DONE */ @@ -6340,8 +6339,8 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi } missing_data: - if (compressing) { - http_compression_buffer_end(s, &res->buf, &tmpbuf, 0); + if (unlikely(compressing)) { + http_compression_buffer_end(s, &res->buf, &tmpbuf, msg->msg_state >= HTTP_MSG_TRAILERS); compressing = 0; } @@ -6410,7 +6409,7 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi return_bad_res_stats_ok: if (unlikely(compressing)) { - http_compression_buffer_end(s, &res->buf, &tmpbuf, 0); + http_compression_buffer_end(s, &res->buf, &tmpbuf, msg->msg_state >= HTTP_MSG_TRAILERS); compressing = 0; }