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:
Christopher Faulet 2020-12-07 18:10:32 +01:00
parent a4009cd610
commit c75668ebff
3 changed files with 9 additions and 9 deletions

View File

@ -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);

View File

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

View File

@ -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.
*/