[nginx] HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
Valentin Bartenev
vbart at nginx.com
Thu Apr 14 12:25:37 UTC 2016
details: http://hg.nginx.org/nginx/rev/8df664ebe037
branches:
changeset: 6515:8df664ebe037
user: Valentin Bartenev <vbart at nginx.com>
date: Thu Apr 14 15:14:15 2016 +0300
description:
HTTP/2: send WINDOW_UPDATE instead of RST_STREAM with NO_ERROR.
After the 92464ebace8e change, it has been discovered that not all
clients follow the RFC and handle RST_STREAM with NO_ERROR properly.
Notably, Chrome currently interprets it as INTERNAL_ERROR and discards
the response.
As a workaround, instead of RST_STREAM the maximum stream window update
will be sent, which will let client to send up to 2 GB of a request body
data before getting stuck on flow control. All the received data will
be silently discarded.
See for details:
http://mailman.nginx.org/pipermail/nginx-devel/2016-April/008143.html
https://bugs.chromium.org/p/chromium/issues/detail?id=603182
diffstat:
src/http/v2/ngx_http_v2.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diffs (37 lines):
diff -r 0aa07850922f -r 8df664ebe037 src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c Thu Apr 14 15:14:15 2016 +0300
+++ b/src/http/v2/ngx_http_v2.c Thu Apr 14 15:14:15 2016 +0300
@@ -3860,11 +3860,33 @@ ngx_http_v2_close_stream(ngx_http_v2_str
}
} else if (!stream->in_closed) {
+#if 0
if (ngx_http_v2_send_rst_stream(h2c, node->id, NGX_HTTP_V2_NO_ERROR)
!= NGX_OK)
{
h2c->connection->error = 1;
}
+#else
+ /*
+ * At the time of writing at least the latest versions of Chrome
+ * do not properly handle RST_STREAM with NO_ERROR status.
+ *
+ * See: https://bugs.chromium.org/p/chromium/issues/detail?id=603182
+ *
+ * As a workaround, the stream window is maximized before closing
+ * the stream. This allows a client to send up to 2 GB of data
+ * before getting blocked on flow control.
+ */
+
+ if (stream->recv_window < NGX_HTTP_V2_MAX_WINDOW
+ && ngx_http_v2_send_window_update(h2c, node->id,
+ NGX_HTTP_V2_MAX_WINDOW
+ - stream->recv_window)
+ != NGX_OK)
+ {
+ h2c->connection->error = 1;
+ }
+#endif
}
}
More information about the nginx-devel
mailing list