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 5242826..ac7fe01 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -6207,7 +6207,7 @@
}
}
- 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 @@
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 @@
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 @@
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 @@
}
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 @@
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;
}