|
|
- From 0cb4b899d370b9d04b3457a1d75dbd658c1a1646 Mon Sep 17 00:00:00 2001
- From: Willy Tarreau <w@1wt.eu>
- Date: Tue, 16 Sep 2014 10:40:38 +0200
- Subject: [PATCH 06/13] MEDIUM: http: enable header manipulation for 101
- responses
-
- Ryan Brock reported that server stickiness did not work for WebSocket
- because the cookies and headers are not modified on 1xx responses. He
- found that his browser correctly presents the cookies learned on 101
- responses, which was not specifically defined in the WebSocket spec,
- nor in the cookie spec. 101 is a very special case. Being part of 1xx,
- it's an interim response. But within 1xx, it's special because it's
- the last HTTP/1 response that transits on the wire, which is different
- from 100 or 102 which may appear multiple times. So in that sense, we
- can consider it as a final response regarding HTTP/1, and it makes
- sense to allow header processing there. Note that we still ensure not
- to mangle the Connection header, which is critical for HTTP upgrade to
- continue to work smoothly with agents that are a bit picky about what
- tokens are found there.
-
- The rspadd rules are now processed for 101 responses as well, but the
- cache-control checks are not performed (since no body is delivered).
-
- Ryan confirmed that this patch works for him.
-
- It would make sense to backport it to 1.5 given that it improves end
- user experience on WebSocket servers.
- (cherry picked from commit ce730de86719d0b5079dd8b0843559e4ff0a1ecc)
- ---
- src/proto_http.c | 12 +++++++-----
- 1 file changed, 7 insertions(+), 5 deletions(-)
-
- diff --git a/src/proto_http.c b/src/proto_http.c
- index 4d27b2c..7e35c8b 100644
- --- a/src/proto_http.c
- +++ b/src/proto_http.c
- @@ -6249,7 +6249,7 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
-
- /* add response headers from the rule sets in the same order */
- list_for_each_entry(wl, &rule_set->rsp_add, list) {
- - if (txn->status < 200)
- + if (txn->status < 200 && txn->status != 101)
- break;
- if (wl->cond) {
- int ret = acl_exec_cond(wl->cond, px, s, txn, SMP_OPT_DIR_RES|SMP_OPT_FINAL);
- @@ -6270,7 +6270,7 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
- }
-
- /* OK that's all we can do for 1xx responses */
- - if (unlikely(txn->status < 200))
- + if (unlikely(txn->status < 200 && txn->status != 101))
- goto skip_header_mangling;
-
- /*
- @@ -6283,7 +6283,7 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
- /*
- * Check for cache-control or pragma headers if required.
- */
- - if ((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC))
- + if (((s->be->options & PR_O_CHK_CACHE) || (s->be->ck_opts & PR_CK_NOC)) && txn->status != 101)
- check_response_for_cacheability(s, rep);
-
- /*
- @@ -6399,9 +6399,11 @@ int http_process_res_common(struct session *s, struct channel *rep, int an_bit,
- * Adjust "Connection: close" or "Connection: keep-alive" if needed.
- * If an "Upgrade" token is found, the header is left untouched in order
- * not to have to deal with some client bugs : some of them fail an upgrade
- - * if anything but "Upgrade" is present in the Connection header.
- + * if anything but "Upgrade" is present in the Connection header. We don't
- + * want to touch any 101 response either since it's switching to another
- + * protocol.
- */
- - if (!(txn->flags & TX_HDR_CONN_UPG) &&
- + if ((txn->status != 101) && !(txn->flags & TX_HDR_CONN_UPG) &&
- (((txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_TUN) ||
- ((s->fe->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL ||
- (s->be->options & PR_O_HTTP_MODE) == PR_O_HTTP_PCL))) {
- --
- 1.8.5.5
-
|