HTTP/2: don't send SETTINGS ACK before already queued DATA frames.

Previously, SETTINGS ACK was sent immediately upon receipt of SETTINGS
frame, before already queued DATA frames created using old SETTINGS.

This incorrect behavior was source of interoperability issues, because
peers rely on the fact that new SETTINGS are in effect after receiving
SETTINGS ACK.

Reported by Feng Li.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
This commit is contained in:
Piotr Sikora 2017-06-02 15:05:32 +03:00
parent ca53600ac0
commit 51a4a414ca
2 changed files with 10 additions and 1 deletions

View File

@ -2032,7 +2032,7 @@ ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos,
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
} }
ngx_http_v2_queue_blocked_frame(h2c, frame); ngx_http_v2_queue_ordered_frame(h2c, frame);
if (window_delta) { if (window_delta) {
if (ngx_http_v2_adjust_windows(h2c, window_delta) != NGX_OK) { if (ngx_http_v2_adjust_windows(h2c, window_delta) != NGX_OK) {

View File

@ -261,6 +261,15 @@ ngx_http_v2_queue_blocked_frame(ngx_http_v2_connection_t *h2c,
} }
static ngx_inline void
ngx_http_v2_queue_ordered_frame(ngx_http_v2_connection_t *h2c,
ngx_http_v2_out_frame_t *frame)
{
frame->next = h2c->last_out;
h2c->last_out = frame;
}
void ngx_http_v2_init(ngx_event_t *rev); void ngx_http_v2_init(ngx_event_t *rev);
void ngx_http_v2_request_headers_init(void); void ngx_http_v2_request_headers_init(void);