aboutsummaryrefslogtreecommitdiff
path: root/src/http/modules/ngx_http_grpc_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/modules/ngx_http_grpc_module.c')
-rw-r--r--src/http/modules/ngx_http_grpc_module.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c
index 992211e73..ab4ad6be1 100644
--- a/src/http/modules/ngx_http_grpc_module.c
+++ b/src/http/modules/ngx_http_grpc_module.c
@@ -84,6 +84,8 @@ typedef struct {
ngx_uint_t pings;
ngx_uint_t settings;
+ off_t length;
+
ssize_t send_window;
size_t recv_window;
@@ -1953,10 +1955,28 @@ ngx_http_grpc_filter_init(void *data)
r = ctx->request;
u = r->upstream;
- u->length = 1;
+ if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
+ || u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED
+ || r->method == NGX_HTTP_HEAD)
+ {
+ ctx->length = 0;
+
+ } else {
+ ctx->length = u->headers_in.content_length_n;
+ }
if (ctx->end_stream) {
+
+ if (ctx->length > 0) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream prematurely closed stream");
+ return NGX_ERROR;
+ }
+
u->length = 0;
+
+ } else {
+ u->length = 1;
}
return NGX_OK;
@@ -1999,6 +2019,12 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
if (ctx->done) {
+ if (ctx->length > 0) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream prematurely closed stream");
+ return NGX_ERROR;
+ }
+
/*
* We have finished parsing the response and the
* remaining control frames. If there are unsent
@@ -2052,6 +2078,17 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
return NGX_ERROR;
}
+ if (ctx->length != -1) {
+ if ((off_t) ctx->rest > ctx->length) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent response body larger "
+ "than indicated content length");
+ return NGX_ERROR;
+ }
+
+ ctx->length -= ctx->rest;
+ }
+
if (ctx->rest > ctx->recv_window) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream violated stream flow control, "