comparison src/http/v2/ngx_http_v2.c @ 6515:8df664ebe037

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
author Valentin Bartenev <vbart@nginx.com>
date Thu, 14 Apr 2016 15:14:15 +0300
parents 0aa07850922f
children ab16126a06a0
comparison
equal deleted inserted replaced
6514:0aa07850922f 6515:8df664ebe037
3858 { 3858 {
3859 h2c->connection->error = 1; 3859 h2c->connection->error = 1;
3860 } 3860 }
3861 3861
3862 } else if (!stream->in_closed) { 3862 } else if (!stream->in_closed) {
3863 #if 0
3863 if (ngx_http_v2_send_rst_stream(h2c, node->id, NGX_HTTP_V2_NO_ERROR) 3864 if (ngx_http_v2_send_rst_stream(h2c, node->id, NGX_HTTP_V2_NO_ERROR)
3864 != NGX_OK) 3865 != NGX_OK)
3865 { 3866 {
3866 h2c->connection->error = 1; 3867 h2c->connection->error = 1;
3867 } 3868 }
3869 #else
3870 /*
3871 * At the time of writing at least the latest versions of Chrome
3872 * do not properly handle RST_STREAM with NO_ERROR status.
3873 *
3874 * See: https://bugs.chromium.org/p/chromium/issues/detail?id=603182
3875 *
3876 * As a workaround, the stream window is maximized before closing
3877 * the stream. This allows a client to send up to 2 GB of data
3878 * before getting blocked on flow control.
3879 */
3880
3881 if (stream->recv_window < NGX_HTTP_V2_MAX_WINDOW
3882 && ngx_http_v2_send_window_update(h2c, node->id,
3883 NGX_HTTP_V2_MAX_WINDOW
3884 - stream->recv_window)
3885 != NGX_OK)
3886 {
3887 h2c->connection->error = 1;
3888 }
3889 #endif
3868 } 3890 }
3869 } 3891 }
3870 3892
3871 if (h2c->state.stream == stream) { 3893 if (h2c->state.stream == stream) {
3872 h2c->state.stream = NULL; 3894 h2c->state.stream = NULL;