|
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
|
|
|