[nginx-tests] Tests: gRPC header length checking tests.
Maxim Dounin
mdounin at mdounin.ru
Sat Jun 20 03:59:22 UTC 2026
details: http://freenginx.org/hg/nginx-tests/rev/9871ad7b7f44
branches:
changeset: 2074:9871ad7b7f44
user: Maxim Dounin <mdounin at mdounin.ru>
date: Sat Jun 20 06:15:11 2026 +0300
description:
Tests: gRPC header length checking tests.
diffstat:
grpc_headers.t | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 64 insertions(+), 1 deletions(-)
diffs (101 lines):
diff --git a/grpc_headers.t b/grpc_headers.t
--- a/grpc_headers.t
+++ b/grpc_headers.t
@@ -10,6 +10,7 @@ use warnings;
use strict;
use Test::More;
+use Socket qw/ CRLF /;
BEGIN { use FindBin; chdir($FindBin::Bin); }
@@ -22,7 +23,7 @@ select STDERR; $| = 1;
select STDOUT; $| = 1;
my $t = Test::Nginx->new()
- ->has(qw/http http_v2 grpc rewrite/)->plan(2)
+ ->has(qw/http http_v2 grpc rewrite/)->plan(7)
->write_file_expand('nginx.conf', <<'EOF');
%%TEST_GLOBALS%%
@@ -39,6 +40,9 @@ http {
~(?<capture>.*) $capture;
}
+ large_client_header_buffers 2 4m;
+ ignore_invalid_headers off;
+
server {
listen 127.0.0.1:8080;
server_name localhost;
@@ -58,6 +62,28 @@ http {
grpc_set_header X-Blah6 "$capture";
grpc_set_header X-Blah "blah $map_capture end";
}
+
+ location /long {
+ grpc_pass 127.0.0.1:8081;
+ grpc_set_header Host "";
+ grpc_set_header TE "";
+ grpc_set_header Content-Length "";
+ grpc_set_header Connection "";
+ }
+
+ location /long_set {
+ grpc_pass 127.0.0.1:8081;
+ grpc_set_header Host "";
+ grpc_set_header TE "";
+ grpc_set_header Content-Length "";
+ grpc_set_header Connection "";
+ grpc_set_header X-Long $a;
+ set $a $args;
+ set $a $a$a$a$a$a$a$a$a$a$a;
+ set $a $a$a$a$a$a$a$a$a$a$a;
+ set $a $a$a$a$a$a$a$a$a$a$a;
+ set $a $a$a$a$a$a$a$a$a$a$a;
+ }
}
server {
@@ -92,4 +118,41 @@ like(http_get('/multi'), qr!blah /multi
}
+TODO: {
+todo_skip 'might coredump', 4
+ unless $t->has_version('1.31.3')
+ or $ENV{TEST_NGINX_UNSAFE};
+local $TODO = 'not yet' unless $t->has_version('1.31.3');
+
+# gRPC module reserves NGX_HTTP_V2_INT_OCTETS (4 bytes) for string lengths,
+# and strings longer than NGX_HTTP_V2_MAX_FIELD (~2 megabytes) will use
+# one more byte for string length
+
+like(http_get('/long?' . ('~' x 2097279)), qr!HTTP/1.!, 'too long :path');
+
+like(http('GE' . ('X' x 2097279) . ' /long?' . ('~' x 16513)
+ . ' HTTP/1.0' . CRLF . CRLF),
+ qr!HTTP/1.!, 'too long :method');
+
+like(http('GET /long?' . ('~' x 16513) . ' HTTP/1.0' . CRLF
+ . 'F' . ('~' x 2097279) . ': ' . ('~' x 16513) . CRLF . CRLF),
+ qr!HTTP/1.!, 'too long header name');
+
+like(http('GET /long?' . ('~' x 16513) . ' HTTP/1.0' . CRLF
+ . 'F' . ('~' x 16513) . ': ' . ('~' x 2097279) . CRLF . CRLF),
+ qr!HTTP/1.!, 'too long header value');
+
+}
+
+TODO: {
+local $TODO = 'not yet' unless $t->has_version('1.31.3');
+
+# this cannot overflow, since header name is short, but still has
+# to be rejected
+
+like(http_get('/long_set?' . ('~' x 210)), qr!500 Internal!,
+ 'too long set header value');
+
+}
+
###############################################################################
More information about the nginx-devel
mailing list