REORG: http: move HTTP Connection response header parsing earlier
Currently, the parsing of the HTTP Connection header for the response
is performed at the same place as the rule sets, which means that after
parsing the beginning of the response, we still have no information on
whether the response is keep-alive compatible or not. Let's do that
earlier.
Note that this is the same code that was moved in the previous function,
both of them are always called in a row so no change of behaviour is
expected.
A future change might consist in having a late analyser to perform the
late header changes such as mangling the connection header. It's quite
painful that currently this is mixed with the rest of the processing
such as filters.
diff --git a/src/proto_http.c b/src/proto_http.c
index b8dff10..6edf113 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -5730,62 +5730,7 @@
if (s->fe->comp || s->be->comp)
select_compression_response_header(s, rep->buf);
- /* FIXME: we should also implement the multipart/byterange method.
- * For now on, we resort to close mode in this case (unknown length).
- */
skip_content_length:
-
- /* end of job, return OK */
- rep->analysers &= ~an_bit;
- rep->analyse_exp = TICK_ETERNITY;
- channel_auto_close(rep);
- return 1;
-
- abort_keep_alive:
- /* A keep-alive request to the server failed on a network error.
- * The client is required to retry. We need to close without returning
- * any other information so that the client retries.
- */
- txn->status = 0;
- rep->analysers = 0;
- s->req->analysers = 0;
- channel_auto_close(rep);
- s->logs.logwait = 0;
- s->logs.level = 0;
- s->rep->flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
- bi_erase(rep);
- stream_int_retnclose(rep->cons, NULL);
- return 0;
-}
-
-/* This function performs all the processing enabled for the current response.
- * It normally returns 1 unless it wants to break. It relies on buffers flags,
- * and updates s->rep->analysers. It might make sense to explode it into several
- * other functions. It works like process_request (see indications above).
- */
-int http_process_res_common(struct session *s, struct channel *rep, int an_bit, struct proxy *px)
-{
- struct http_txn *txn = &s->txn;
- struct http_msg *msg = &txn->rsp;
- struct proxy *cur_proxy;
- struct cond_wordlist *wl;
- struct http_res_rule *http_res_last_rule = NULL;
-
- DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
- now_ms, __FUNCTION__,
- s,
- rep,
- rep->rex, rep->wex,
- rep->flags,
- rep->buf->i,
- rep->analysers);
-
- if (unlikely(msg->msg_state < HTTP_MSG_BODY)) /* we need more data */
- return 0;
-
- rep->analysers &= ~an_bit;
- rep->analyse_exp = TICK_ETERNITY;
-
/* Now we have to check if we need to modify the Connection header.
* This is more difficult on the response than it is on the request,
* because we can have two different HTTP versions and we don't know
@@ -5862,6 +5807,57 @@
/* we want to have the response time before we start processing it */
s->logs.t_data = tv_ms_elapsed(&s->logs.tv_accept, &now);
+ /* end of job, return OK */
+ rep->analysers &= ~an_bit;
+ rep->analyse_exp = TICK_ETERNITY;
+ channel_auto_close(rep);
+ return 1;
+
+ abort_keep_alive:
+ /* A keep-alive request to the server failed on a network error.
+ * The client is required to retry. We need to close without returning
+ * any other information so that the client retries.
+ */
+ txn->status = 0;
+ rep->analysers = 0;
+ s->req->analysers = 0;
+ channel_auto_close(rep);
+ s->logs.logwait = 0;
+ s->logs.level = 0;
+ s->rep->flags &= ~CF_EXPECT_MORE; /* speed up sending a previous response */
+ bi_erase(rep);
+ stream_int_retnclose(rep->cons, NULL);
+ return 0;
+}
+
+/* This function performs all the processing enabled for the current response.
+ * It normally returns 1 unless it wants to break. It relies on buffers flags,
+ * and updates s->rep->analysers. It might make sense to explode it into several
+ * other functions. It works like process_request (see indications above).
+ */
+int http_process_res_common(struct session *s, struct channel *rep, int an_bit, struct proxy *px)
+{
+ struct http_txn *txn = &s->txn;
+ struct http_msg *msg = &txn->rsp;
+ struct proxy *cur_proxy;
+ struct cond_wordlist *wl;
+ struct http_res_rule *http_res_last_rule = NULL;
+
+ DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n",
+ now_ms, __FUNCTION__,
+ s,
+ rep,
+ rep->rex, rep->wex,
+ rep->flags,
+ rep->buf->i,
+ rep->analysers);
+
+ if (unlikely(msg->msg_state < HTTP_MSG_BODY)) /* we need more data */
+ return 0;
+
+ rep->analysers &= ~an_bit;
+ rep->analyse_exp = TICK_ETERNITY;
+
/* The stats applet needs to adjust the Connection header but we don't
* apply any filter there.
*/