# HG changeset patch # User Roman Arutyunyan # Date 1597131699 -10800 # Node ID b66a2a041d7ee93db42c1cde66b7cf91aabdfe3b # Parent 69033a50c3aed91c3d203fa167b774adf782ce04 QUIC: fixed ngx_http_test_reading() for QUIC streams. Previously this function generated an error trying to figure out if client shut down the write end of the connection. The reason for this error was that a QUIC stream has no socket descriptor. However checking for eof is not the right thing to do for an HTTP/3 QUIC stream since HTTP/3 clients are expected to shut down the write end of the stream after sending the request. Now the function handles QUIC streams separately. It checks if c->read->error is set. The error flags for c->read and c->write are now set for all streams when closing the QUIC connection instead of setting the pending_eof flag. diff --git a/src/event/ngx_event_quic.c b/src/event/ngx_event_quic.c --- a/src/event/ngx_event_quic.c +++ b/src/event/ngx_event_quic.c @@ -1460,7 +1460,7 @@ ngx_quic_close_timer_handler(ngx_event_t static ngx_int_t ngx_quic_close_streams(ngx_connection_t *c, ngx_quic_connection_t *qc) { - ngx_event_t *rev; + ngx_event_t *rev, *wev; ngx_rbtree_t *tree; ngx_rbtree_node_t *node; ngx_quic_stream_t *qs; @@ -1486,8 +1486,12 @@ ngx_quic_close_streams(ngx_connection_t qs = (ngx_quic_stream_t *) node; rev = qs->c->read; + rev->error = 1; rev->ready = 1; - rev->pending_eof = 1; + + wev = qs->c->write; + wev->error = 1; + wev->ready = 1; ngx_post_event(rev, &ngx_posted_events); @@ -4005,6 +4009,10 @@ ngx_quic_stream_recv(ngx_connection_t *c qc = pc->quic; rev = c->read; + if (rev->error) { + return NGX_ERROR; + } + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "quic stream id 0x%xL recv: eof:%d, avail:%z", qs->id, rev->pending_eof, b->last - b->pos); @@ -4093,6 +4101,7 @@ ngx_quic_stream_send(ngx_connection_t *c u_char *p, *end; size_t fsize, limit, n, len; uint64_t sent, unacked; + ngx_event_t *wev; ngx_connection_t *pc; ngx_quic_frame_t *frame; ngx_quic_stream_t *qs; @@ -4101,8 +4110,9 @@ ngx_quic_stream_send(ngx_connection_t *c qs = c->qs; pc = qs->parent; qc = pc->quic; - - if (qc->closing) { + wev = c->write; + + if (wev->error) { return NGX_ERROR; } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -3022,6 +3022,19 @@ ngx_http_test_reading(ngx_http_request_t #endif +#if (NGX_HTTP_QUIC) + + if (c->qs) { + if (c->read->error) { + err = 0; + goto closed; + } + + return; + } + +#endif + #if (NGX_HAVE_KQUEUE) if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {