Hello,
I noticed that in some situations not all queued HTTP/2 frames may be sent before closing the HTTP/2 connection.

This could happen when the ngx_http_v2_finalize_connection is called with some frames in the h2c->last_out queue and with the c->write not ready. In such situation, the GOAWAY frame is pushed into the queue and ngx_http_v2_send_output_queue is called immediately, but no frames are sent due to the not ready c->write. During normal processing, these frames would be sent when the socket became ready again, but during the connection finalization the NGX_AGAIN is silently ignored, the queue in h2c->last_out is thrown away and the TCP connection is closed.

Connection finalization with a non-empty queue of frames could be triggered by some error in the connection itself (disconnected client, ...) or by breaking some constraints like a number of concurrent streams. In the first case, the "best-effort" ngx_http_v2_send_output_queue before shutdown is the only thing we can do. But in the second case, the client is still able to receive the remaining frames, some of them useful for him (GOAWAY frame with an error reason, RST_STREAM frame providing information, if the request could be repeated), but these queued frames are never sent.

I think if it is worth modifying the ngx_http_v2_finalize_connection and ngx_http_v2_lingering_close in such way, that a lingering write handler would be set in a similar way as the lingering read handler to allow the queue to be sent until the lingering timeout. Any thoughts?

Also, I'm not fully sure about the reason behind that the h2c->last_out being set to NULL in ngx_http_v2_finalize_connection, when the event handlers of streams could generate more frames and again populating the h2c->last_out. Is there some reason why it is done in this way?

Sincerely
Jiří Setnička
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel

Reply via email to