mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-05-06 09:48:00 +00:00
BUG/MINOR: http: Establish a tunnel for all 2xx responses to a CONNECT
As stated in the rfc7231, section 4.3.6, an HTTP tunnel via a CONNECT method is successfully established if the server replies with any 2xx status code. However, only 200 responses are considered as valid. With this patch, any 2xx responses are now considered to estalish the tunnel. This patch may be backported on demand to all stable versions and adapted for the legacy HTTP. It works this way since a very long time and nobody complains.
This commit is contained in:
parent
a4009cd610
commit
c75668ebff
@ -278,7 +278,7 @@ static int h1_postparse_res_hdrs(struct h1m *h1m, union h1_sl *h1sl, struct htx
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (((h1m->flags & H1_MF_METH_CONNECT) && code == 200) || code == 101) {
|
||||
if (((h1m->flags & H1_MF_METH_CONNECT) && code >= 200 && code < 300) || code == 101) {
|
||||
/* Switch successful replies to CONNECT requests and
|
||||
* protocol switching to tunnel mode. */
|
||||
h1_set_tunnel_mode(h1m);
|
||||
|
@ -1635,7 +1635,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
http_capture_headers(htx, s->res_cap, sess->fe->rsp_cap);
|
||||
|
||||
/* Skip parsing if no content length is possible. */
|
||||
if (unlikely((txn->meth == HTTP_METH_CONNECT && txn->status == 200) ||
|
||||
if (unlikely((txn->meth == HTTP_METH_CONNECT && txn->status >= 200 && txn->status < 300) ||
|
||||
txn->status == 101)) {
|
||||
/* Either we've established an explicit tunnel, or we're
|
||||
* switching the protocol. In both cases, we're very unlikely
|
||||
@ -2132,7 +2132,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
|
||||
if (msg->msg_state >= HTTP_MSG_ENDING)
|
||||
goto ending;
|
||||
|
||||
if ((txn->meth == HTTP_METH_CONNECT && txn->status == 200) || txn->status == 101 ||
|
||||
if ((txn->meth == HTTP_METH_CONNECT && txn->status >= 200 && txn->status < 300) || txn->status == 101 ||
|
||||
(!(msg->flags & HTTP_MSGF_XFER_LEN) && !HAS_RSP_DATA_FILTERS(s))) {
|
||||
msg->msg_state = HTTP_MSG_ENDING;
|
||||
goto ending;
|
||||
@ -2187,7 +2187,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
|
||||
}
|
||||
}
|
||||
|
||||
if ((txn->meth == HTTP_METH_CONNECT && txn->status == 200) || txn->status == 101 ||
|
||||
if ((txn->meth == HTTP_METH_CONNECT && txn->status >= 200 && txn->status < 300) || txn->status == 101 ||
|
||||
!(msg->flags & HTTP_MSGF_XFER_LEN)) {
|
||||
msg->msg_state = HTTP_MSG_TUNNEL;
|
||||
goto ending;
|
||||
|
10
src/mux_h1.c
10
src/mux_h1.c
@ -934,7 +934,7 @@ static void h1_set_cli_conn_mode(struct h1s *h1s, struct h1m *h1m)
|
||||
|
||||
if (h1m->flags & H1_MF_RESP) {
|
||||
/* Output direction: second pass */
|
||||
if ((h1s->meth == HTTP_METH_CONNECT && h1s->status == 200) ||
|
||||
if ((h1s->meth == HTTP_METH_CONNECT && h1s->status >= 200 && h1s->status < 300) ||
|
||||
h1s->status == 101) {
|
||||
/* Either we've established an explicit tunnel, or we're
|
||||
* switching the protocol. In both cases, we're very unlikely to
|
||||
@ -994,7 +994,7 @@ static void h1_set_srv_conn_mode(struct h1s *h1s, struct h1m *h1m)
|
||||
|
||||
if (h1m->flags & H1_MF_RESP) {
|
||||
/* Input direction: second pass */
|
||||
if ((h1s->meth == HTTP_METH_CONNECT && h1s->status == 200) ||
|
||||
if ((h1s->meth == HTTP_METH_CONNECT && h1s->status >= 200 && h1s->status < 300) ||
|
||||
h1s->status == 101) {
|
||||
/* Either we've established an explicit tunnel, or we're
|
||||
* switching the protocol. In both cases, we're very unlikely to
|
||||
@ -1817,8 +1817,8 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
||||
if ((h1s->meth != HTTP_METH_CONNECT &&
|
||||
(h1m->flags & (H1_MF_VER_11|H1_MF_RESP|H1_MF_CLEN|H1_MF_CHNK|H1_MF_XFER_LEN)) ==
|
||||
(H1_MF_VER_11|H1_MF_XFER_LEN)) ||
|
||||
(h1s->status >= 200 && h1s->status != 204 && h1s->status != 304 &&
|
||||
h1s->meth != HTTP_METH_HEAD && !(h1s->meth == HTTP_METH_CONNECT && h1s->status == 200) &&
|
||||
(h1s->status >= 200 && h1s->status != 204 && h1s->status != 304 && h1s->meth != HTTP_METH_HEAD &&
|
||||
!(h1s->meth == HTTP_METH_CONNECT && h1s->status >= 200 && h1s->status < 300) &&
|
||||
(h1m->flags & (H1_MF_VER_11|H1_MF_RESP|H1_MF_CLEN|H1_MF_CHNK|H1_MF_XFER_LEN)) ==
|
||||
(H1_MF_VER_11|H1_MF_RESP|H1_MF_XFER_LEN))) {
|
||||
/* chunking needed but header not seen */
|
||||
@ -1862,7 +1862,7 @@ static size_t h1_process_output(struct h1c *h1c, struct buffer *buf, size_t coun
|
||||
h1_set_req_tunnel_mode(h1s);
|
||||
}
|
||||
else if ((h1m->flags & H1_MF_RESP) &&
|
||||
((h1s->meth == HTTP_METH_CONNECT && h1s->status == 200) || h1s->status == 101)) {
|
||||
((h1s->meth == HTTP_METH_CONNECT && h1s->status >= 200 && h1s->status < 300) || h1s->status == 101)) {
|
||||
/* a successful reply to a CONNECT or a protocol switching is sent
|
||||
* to the client. Switch the response to tunnel mode.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user