# HG changeset patch # User Roman Arutyunyan <a...@nginx.com> # Date 1643611590 -10800 # Mon Jan 31 09:46:30 2022 +0300 # Branch quic # Node ID d3c6dea9454c48ded14b8c087dffc4dea46f78ef # Parent 8dcb9908989401d750b14fe5dccf444a5485c23d HTTP/3: proper uni stream closure detection.
Previously, closure detection for server-initiated uni streams was not properly implemented. Instead, HTTP/3 code relied on QUIC code posting the read event and setting rev->error when it needed to close the stream. Then, regular uni stream read handler called c->recv() and received error, which closed the stream. This was an ad-hoc solution. If, for whatever reason, the read handler was called earlier, c->recv() would return 0, which would also close the stream. Now server-initiated uni streams have a separate read event handler for tracking stream closure. The handler calls c->recv(), which normally returns 0, but may return error in case of closure. diff --git a/src/http/v3/ngx_http_v3_uni.c b/src/http/v3/ngx_http_v3_uni.c --- a/src/http/v3/ngx_http_v3_uni.c +++ b/src/http/v3/ngx_http_v3_uni.c @@ -26,6 +26,7 @@ typedef struct { static void ngx_http_v3_close_uni_stream(ngx_connection_t *c); static void ngx_http_v3_uni_read_handler(ngx_event_t *rev); +static void ngx_http_v3_dummy_read_handler(ngx_event_t *wev); static void ngx_http_v3_dummy_write_handler(ngx_event_t *wev); static void ngx_http_v3_push_cleanup(void *data); static ngx_connection_t *ngx_http_v3_get_uni_stream(ngx_connection_t *c, @@ -252,6 +253,32 @@ failed: static void +ngx_http_v3_dummy_read_handler(ngx_event_t *rev) +{ + u_char ch; + ngx_connection_t *c; + + c = rev->data; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 dummy read handler"); + + if (rev->ready) { + if (c->recv(c, &ch, 1) != 0) { + ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_NO_ERROR, NULL); + ngx_http_v3_close_uni_stream(c); + return; + } + } + + if (ngx_handle_read_event(rev, 0) != NGX_OK) { + ngx_http_v3_finalize_connection(c, NGX_HTTP_V3_ERR_INTERNAL_ERROR, + NULL); + ngx_http_v3_close_uni_stream(c); + } +} + + +static void ngx_http_v3_dummy_write_handler(ngx_event_t *wev) { ngx_connection_t *c; @@ -393,7 +420,7 @@ ngx_http_v3_get_uni_stream(ngx_connectio sc->data = us; - sc->read->handler = ngx_http_v3_uni_read_handler; + sc->read->handler = ngx_http_v3_dummy_read_handler; sc->write->handler = ngx_http_v3_dummy_write_handler; if (index >= 0) { @@ -409,6 +436,8 @@ ngx_http_v3_get_uni_stream(ngx_connectio goto failed; } + ngx_post_event(sc->read, &ngx_posted_events); + return sc; failed: _______________________________________________ nginx-devel mailing list -- nginx-devel@nginx.org To unsubscribe send an email to nginx-devel-le...@nginx.org