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