h2s_close(h2s);
}
+ /* Unblock busy server h2s waiting for the response headers to validate
+ * the tunnel establishment or the end of the response of an oborted
+ * tunnel
+ */
+ if ((h2s->flags & (H2_SF_BODY_TUNNEL|H2_SF_BLK_MBUSY)) == (H2_SF_BODY_TUNNEL|H2_SF_BLK_MBUSY) ||
+ (h2s->flags & (H2_SF_TUNNEL_ABRT|H2_SF_ES_RCVD|H2_SF_BLK_MBUSY)) == (H2_SF_TUNNEL_ABRT|H2_SF_ES_RCVD|H2_SF_BLK_MBUSY)) {
+ TRACE_STATE("Unblock h2s blocked on tunnel establishment/abort", H2_EV_RX_FRAME|H2_EV_RX_DATA, h2c->conn, h2s);
+ h2s->flags &= ~H2_SF_BLK_MBUSY;
+ }
+
TRACE_USER("rcvd H2 response", H2_EV_RX_FRAME|H2_EV_RX_HDR, h2c->conn, 0, &h2s->rxbuf);
TRACE_LEAVE(H2_EV_RX_FRAME|H2_EV_RX_HDR, h2c->conn, h2s);
return h2s;
}
}
+ /* Unblock busy server h2s waiting for the end of the response for an
+ * aborted tunnel
+ */
+ if ((h2c->flags & H2_CF_IS_BACK) &&
+ (h2s->flags & (H2_SF_TUNNEL_ABRT|H2_SF_ES_RCVD|H2_SF_BLK_MBUSY)) == (H2_SF_TUNNEL_ABRT|H2_SF_ES_RCVD|H2_SF_BLK_MBUSY)) {
+ TRACE_STATE("Unblock h2s blocked on tunnel abort", H2_EV_RX_FRAME|H2_EV_RX_DATA, h2c->conn, h2s);
+ h2s->flags &= ~H2_SF_BLK_MBUSY;
+ }
+
TRACE_LEAVE(H2_EV_RX_FRAME|H2_EV_RX_DATA, h2c->conn, h2s);
return 1;
}
else if (type != HTX_BLK_DATA)
goto end;
+ else if ((h2c->flags & H2_CF_IS_BACK) &&
+ (h2s->flags & (H2_SF_HEADERS_RCVD|H2_SF_BODY_TUNNEL)) == H2_SF_BODY_TUNNEL) {
+ /* The response HEADERS frame not received yet. Thus the tunnel
+ * is not fully established yet. In this situation, we block
+ * data sending.
+ */
+ h2s->flags |= H2_SF_BLK_MBUSY;
+ TRACE_STATE("Request DATA frame blocked waiting for tunnel establishment", H2_EV_TX_FRAME|H2_EV_TX_DATA, h2c->conn, h2s);
+ goto end;
+ }
mbuf = br_tail(h2c->mbuf);
retry: