Skip to content

Commit 6b81d9a

Browse files
manu-nscapflam
authored andcommitted
BUG/MEDIUM: http-ana: apply tunnel timeout with data filters
The tunnel timeout is installed by process_stream() only once all analysers are gone. HTTP data filters keep their transfer and end analysers attached after a protocol upgrade. A stream using, for example, set-bandwidth-limit therefore remains on its client and server timeouts even though both HTTP messages are in tunnel mode. A short client timeout can close a WebSocket before its heartbeat. Apply the per-stream tunnel timeout when the second HTTP message enters tunnel mode. Data-filter analysers remain active and continue to process tunneled data. It should be backported as far as 2.6.
1 parent 559c570 commit 6b81d9a

2 files changed

Lines changed: 15 additions & 3 deletions

File tree

reg-tests/http-messaging/websocket.vtc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ server s1 {
2828

2929
recv 4
3030
send "PONG"
31+
expect_close
3132
} -start
3233

3334
# non-conformant server: no websocket key
@@ -111,6 +112,13 @@ haproxy hap -conf {
111112

112113
listen fe1
113114
bind "fd@${fe1}"
115+
timeout client 100ms
116+
timeout server 100ms
117+
timeout tunnel 1s
118+
filter bwlim-in upload default-limit 1m default-period 1s
119+
filter bwlim-out download default-limit 1m default-period 1s
120+
http-request set-bandwidth-limit upload
121+
http-request set-bandwidth-limit download
114122
server s1 ${s1_addr}:${s1_port}
115123

116124
listen fe2
@@ -141,8 +149,10 @@ client c1 -connect ${hap_fe1_sock} {
141149
expect resp.http.upgrade == "websocket"
142150
expect resp.http.sec-websocket-accept == "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
143151

152+
delay 0.2
144153
send "PING"
145154
recv 4
155+
expect_close
146156
} -run
147157

148158
# missing websocket key

src/http_ana.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4588,14 +4588,14 @@ static void http_end_request(struct stream *s)
45884588
* direction, and sometimes for a close to be effective.
45894589
*/
45904590
if (txn->flags & TX_CON_WANT_TUN) {
4591-
/* Tunnel mode will not have any analyser so it needs to
4592-
* poll for reads.
4593-
*/
4591+
/* Tunnel mode needs to poll for reads. */
45944592
channel_auto_read(&s->req);
45954593
txn->req.msg_state = HTTP_MSG_TUNNEL;
45964594
s->scb->flags &= ~SC_FL_NOHALF;
45974595
if (txn->rsp.msg_state != HTTP_MSG_TUNNEL)
45984596
s->res.flags |= CF_WAKE_ONCE;
4597+
else if (s->tunnel_timeout)
4598+
s->scf->ioto = s->scb->ioto = s->tunnel_timeout;
45994599
}
46004600
else {
46014601
/* we're not expecting any new data to come for this
@@ -4708,6 +4708,8 @@ static void http_end_response(struct stream *s)
47084708
txn->rsp.msg_state = HTTP_MSG_TUNNEL;
47094709
if (txn->req.msg_state != HTTP_MSG_TUNNEL)
47104710
s->req.flags |= CF_WAKE_ONCE;
4711+
else if (s->tunnel_timeout)
4712+
s->scf->ioto = s->scb->ioto = s->tunnel_timeout;
47114713
}
47124714
else {
47134715
/* we're not expecting any new data to come for this

0 commit comments

Comments
 (0)