[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