Welcome! Log In Create A New Profile

Advanced

[nginx] gRPC: RST_STREAM(NO_ERROR) handling (ticket #1792).

April 23, 2020 08:12AM
details: https://hg.nginx.org/nginx/rev/2096b21fcd10
branches:
changeset: 7646:2096b21fcd10
user: Ruslan Ermilov <ru@nginx.com>
date: Thu Apr 23 15:10:24 2020 +0300
description:
gRPC: RST_STREAM(NO_ERROR) handling (ticket #1792).

As per https://tools.ietf.org/html/rfc7540#section-8.1,

: A server can send a complete response prior to the client
: sending an entire request if the response does not depend on
: any portion of the request that has not been sent and
: received. When this is true, a server MAY request that the
: client abort transmission of a request without error by
: sending a RST_STREAM with an error code of NO_ERROR after
: sending a complete response (i.e., a frame with the
: END_STREAM flag). Clients MUST NOT discard responses as a
: result of receiving such a RST_STREAM, though clients can
: always discard responses at their discretion for other
: reasons.

Previously, RST_STREAM(NO_ERROR) received from upstream after
a frame with the END_STREAM flag was incorrectly treated as an
error. Now, a single RST_STREAM(NO_ERROR) is properly handled.

This fixes problems observed with modern grpc-c [1], as well
as with the Go gRPC module.

[1] https://github.com/grpc/grpc/pull/1661

diffstat:

src/http/modules/ngx_http_grpc_module.c | 26 ++++++++++++++++++++------
1 files changed, 20 insertions(+), 6 deletions(-)

diffs (57 lines):

diff -r ed3a10cf88e8 -r 2096b21fcd10 src/http/modules/ngx_http_grpc_module.c
--- a/src/http/modules/ngx_http_grpc_module.c Thu Apr 23 15:10:21 2020 +0300
+++ b/src/http/modules/ngx_http_grpc_module.c Thu Apr 23 15:10:24 2020 +0300
@@ -120,6 +120,7 @@ typedef struct {
unsigned end_stream:1;
unsigned done:1;
unsigned status:1;
+ unsigned rst:1;

ngx_http_request_t *request;

@@ -1205,6 +1206,7 @@ ngx_http_grpc_reinit_request(ngx_http_re
ctx->end_stream = 0;
ctx->done = 0;
ctx->status = 0;
+ ctx->rst = 0;
ctx->connection = NULL;

return NGX_OK;
@@ -2088,7 +2090,9 @@ ngx_http_grpc_filter(void *data, ssize_t
return NGX_ERROR;
}

- if (ctx->stream_id && ctx->done) {
+ if (ctx->stream_id && ctx->done
+ && ctx->type != NGX_HTTP_V2_RST_STREAM_FRAME)
+ {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream sent frame for closed stream %ui",
ctx->stream_id);
@@ -2131,11 +2135,21 @@ ngx_http_grpc_filter(void *data, ssize_t
return NGX_ERROR;
}

- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "upstream rejected request with error %ui",
- ctx->error);
-
- return NGX_ERROR;
+ if (ctx->error || !ctx->done) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream rejected request with error %ui",
+ ctx->error);
+ return NGX_ERROR;
+ }
+
+ if (ctx->rst) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent frame for closed stream %ui",
+ ctx->stream_id);
+ return NGX_ERROR;
+ }
+
+ ctx->rst = 1;
}

if (ctx->type == NGX_HTTP_V2_GOAWAY_FRAME) {
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[nginx] gRPC: RST_STREAM(NO_ERROR) handling (ticket #1792).

ru@nginx.com 880 April 23, 2020 08:12AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 285
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready