[master] b12b829 Avoid leaving the h2sess hanging on return (fail)
Dag Haavi Finstad
daghf at varnish-software.com
Fri Mar 9 14:38:08 UTC 2018
commit b12b8294cd431c9f82b54bafac5614d76e9ce744
Author: Dag Haavi Finstad <daghf at varnish-software.com>
Date: Fri Mar 9 15:35:01 2018 +0100
Avoid leaving the h2sess hanging on return (fail)
If we fail a stream early from VCL via return (fail) after sending a
request body, the h2 sess will be stuck waiting forever.
diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c
index 542a10e..8b61020 100644
--- a/bin/varnishd/http2/cache_http2_proto.c
+++ b/bin/varnishd/http2/cache_http2_proto.c
@@ -509,6 +509,7 @@ h2_do_req(struct worker *wrk, void *priv)
{
struct req *req;
struct h2_req *r2;
+ struct h2_sess *h2;
CAST_OBJ_NOTNULL(req, priv, REQ_MAGIC);
CAST_OBJ_NOTNULL(r2, req->transport_priv, H2_REQ_MAGIC);
@@ -517,10 +518,16 @@ h2_do_req(struct worker *wrk, void *priv)
req->http->conds = 1;
if (CNT_Request(wrk, req) != REQ_FSM_DISEMBARK) {
AZ(req->ws->r);
+ h2 = r2->h2sess;
+ CHECK_OBJ_NOTNULL(h2, H2_SESS_MAGIC);
+ Lck_Lock(&h2->sess->mtx);
r2->scheduled = 0;
r2->state = H2_S_CLOSED;
- if (r2->h2sess->error)
- AZ(pthread_cond_signal(r2->h2sess->cond));
+ if (h2->mailcall == r2) {
+ h2->mailcall = NULL;
+ AZ(pthread_cond_signal(h2->cond));
+ }
+ Lck_Unlock(&h2->sess->mtx);
}
THR_SetRequest(NULL);
}
diff --git a/bin/varnishtest/tests/t02005.vtc b/bin/varnishtest/tests/t02005.vtc
index c80432b..2bcd1da 100644
--- a/bin/varnishtest/tests/t02005.vtc
+++ b/bin/varnishtest/tests/t02005.vtc
@@ -2,15 +2,30 @@ varnishtest "H2 POST"
barrier b1 cond 2
+barrier b2 sock 2
+barrier b3 sock 2
+
server s1 {
rxreq
expect req.http.content-length == 7
expect req.http.transfer-encoding == <undef>
barrier b1 sync
txresp -hdr "Content-Type: text/plain" -body response
+
+ rxreq
+ txresp
} -start
-varnish v1 -vcl+backend {} -cliok "param.set feature +http2" -start
+varnish v1 -vcl+backend {
+ import vtc;
+ sub vcl_recv {
+ if (req.url == "/a") {
+ vtc.barrier_sync("${b2_sock}");
+ vtc.barrier_sync("${b3_sock}");
+ return (fail);
+ }
+ }
+} -cliok "param.set feature +http2" -start
varnish v1 -cliok "param.set debug +syncvsl"
logexpect l1 -v v1 -g raw {
@@ -41,5 +56,27 @@ client c1 {
stream 0 -wait
} -run
+client c1 {
+ stream 0 {
+ barrier b2 sync
+ delay 1
+ barrier b3 sync
+ rxwinup
+ } -start
+ stream 1 {
+ txreq -url "/a" -req POST -nostrend
+ txdata -datalen 100
+ rxresp
+ rxwinup
+ expect resp.status == 503
+ } -run
+ stream 3 {
+ txreq -url "/b"
+ rxresp
+ expect resp.status == 200
+ } -run
+ stream 0 -wait
+} -run
+
logexpect l1 -wait
More information about the varnish-commit
mailing list