@@ -23,7 +23,7 @@ use Test::Nginx::HTTP2;
23
23
select STDERR ; $| = 1;
24
24
select STDOUT ; $| = 1;
25
25
26
- my $t = Test::Nginx-> new()-> has(qw/ http http_v2 grpc mirror/ );
26
+ my $t = Test::Nginx-> new()-> has(qw/ http http_v2 grpc mirror proxy / );
27
27
28
28
$t -> write_file_expand(' nginx.conf' , <<'EOF' );
29
29
39
39
40
40
server {
41
41
listen 127.0.0.1:8080 http2;
42
+ listen 127.0.0.1:8082;
42
43
server_name localhost;
43
44
44
45
location /mirror { }
@@ -48,12 +49,22 @@ http {
48
49
add_header X-Body $request_body;
49
50
mirror /mirror;
50
51
}
52
+
53
+ location /proxy {
54
+ proxy_pass http://127.0.0.1:8082/mirror;
55
+ proxy_intercept_errors on;
56
+ error_page 404 = @fallback;
57
+ }
58
+
59
+ location @fallback {
60
+ grpc_pass 127.0.0.1:8081;
61
+ }
51
62
}
52
63
}
53
64
54
65
EOF
55
66
56
- $t -> try_run(' no grpc' )-> plan(9 );
67
+ $t -> try_run(' no grpc' )-> plan(12 );
57
68
58
69
# ##############################################################################
59
70
@@ -77,6 +88,28 @@ $frames = $f->{http_end}();
77
88
($frame ) = grep { $_ -> {type } eq " HEADERS" } @$frames ;
78
89
is($frame -> {headers }{' x-body' }, ' Hello' , ' request body in memory' );
79
90
91
+ # expect body cleanup is disabled with preserve_output (ticket #1565).
92
+ # after request body first bytes were proxied on behalf of initial window size,
93
+ # send response header from upstream, this leads to body cleanup code path
94
+
95
+ $frames = $f -> {http_start }(' /proxy' );
96
+ is(eval (join ' +' , map { $_ -> {length } } grep { $_ -> {type } eq " DATA" } @$frames ),
97
+ 65535, ' preserve_output - first body bytes' );
98
+
99
+ TODO: {
100
+ local $TODO = ' not yet' unless $t -> has_version(' 1.15.1' );
101
+
102
+ $frames = $f -> {http_end }();
103
+ is(eval (join ' +' , map { $_ -> {length } } grep { $_ -> {type } eq " DATA" } @$frames ),
104
+ 465, ' preserve_output - last body bytes' );
105
+
106
+ like(` grep -F '[crit]' ${\( $t ->testdir())}/error.log` , qr / ^$ / s , ' no crits' );
107
+
108
+ }
109
+
110
+ $t -> todo_alerts() if $t -> read_file(' nginx.conf' ) =~ / sendfile on/
111
+ and !$t -> has_version(' 1.15.1' );
112
+
80
113
# ##############################################################################
81
114
82
115
sub grpc {
@@ -94,12 +127,13 @@ sub grpc {
94
127
$f -> {http_start } = sub {
95
128
($uri , my %extra ) = @_ ;
96
129
$s = Test::Nginx::HTTP2-> new() if !defined $s ;
97
- $s -> new_stream({ body => ' Hello' , headers => [
130
+ my ($body ) = $uri eq ' /proxy' ? ' Hello' x 13200 : ' Hello' ;
131
+ $s -> new_stream({ body => $body , headers => [
98
132
{ name => ' :method' , value => ' POST' , mode => 0 },
99
133
{ name => ' :scheme' , value => ' http' , mode => 0 },
100
134
{ name => ' :path' , value => $uri },
101
135
{ name => ' :authority' , value => ' localhost' },
102
- { name => ' content-length' , value => ' 5 ' }]});
136
+ { name => ' content-length' , value => length ( $body ) }]});
103
137
104
138
if (!$extra {reuse }) {
105
139
eval {
@@ -124,7 +158,9 @@ sub grpc {
124
158
pure => 1, preface => " " ) or return ;
125
159
}
126
160
127
- my $frames = $c -> read (all => [{ fin => 1 }]);
161
+ my $frames = $uri eq ' /proxy'
162
+ ? $c -> read (all => [{ length => 65535 }])
163
+ : $c -> read (all => [{ fin => 1 }]);
128
164
129
165
if (!$extra {reuse }) {
130
166
$c -> h2_settings(0);
@@ -140,6 +176,15 @@ sub grpc {
140
176
{ name => ' :status' , value => ' 200' , mode => 0 },
141
177
{ name => ' content-type' , value => ' application/grpc' },
142
178
]}, $sid );
179
+
180
+ # reopen window for request body after response HEADERS is sent
181
+
182
+ if ($uri eq ' /proxy' ) {
183
+ $c -> h2_window(2**16, $sid );
184
+ $c -> h2_window(2**16);
185
+ return $c -> read (all => [{ sid => $sid , fin => 1 }]);
186
+ }
187
+
143
188
$c -> h2_body(' Hello world' , { body_more => 1 });
144
189
$c -> new_stream({ headers => [
145
190
{ name => ' grpc-status' , value => ' 0' , mode => 2 },
0 commit comments