comparison h2_absolute_redirect.t @ 1732:41ca4b00c2d0

Tests: added absolute_redirect and Location tests for HTTP/2.
author Sergey Kandaurov <pluknet@nginx.com>
date Wed, 15 Sep 2021 20:32:11 +0300
parents http_absolute_redirect.t@c9b4c0ef5059
children 236d038dc04a
comparison
equal deleted inserted replaced
1731:c9b4c0ef5059 1732:41ca4b00c2d0
1 #!/usr/bin/perl
2
3 # (C) Sergey Kandaurov
4 # (C) Nginx, Inc.
5
6 # Tests for absolute_redirect directive and Location escaping.
7
8 ###############################################################################
9
10 use warnings;
11 use strict;
12
13 use Test::More;
14
15 BEGIN { use FindBin; chdir($FindBin::Bin); }
16
17 use lib 'lib';
18 use Test::Nginx;
19 use Test::Nginx::HTTP2;
20
21 ###############################################################################
22
23 select STDERR; $| = 1;
24 select STDOUT; $| = 1;
25
26 my $t = Test::Nginx->new()->has(qw/http http_v2 proxy rewrite/)
27 ->write_file_expand('nginx.conf', <<'EOF');
28
29 %%TEST_GLOBALS%%
30
31 daemon off;
32
33 events {
34 }
35
36 http {
37 %%TEST_GLOBALS_HTTP%%
38
39 absolute_redirect off;
40
41 server {
42 listen 127.0.0.1:8080 http2;
43 server_name on;
44
45 absolute_redirect on;
46 error_page 400 /return301;
47
48 location / { }
49
50 location /auto/ {
51 proxy_pass http://127.0.0.1:8080;
52 }
53
54 location "/auto sp/" {
55 proxy_pass http://127.0.0.1:8080;
56 }
57
58 location /return301 {
59 return 301 /redirect;
60 }
61
62 location /return301/name {
63 return 301 /redirect;
64 server_name_in_redirect on;
65 }
66
67 location /return301/port {
68 return 301 /redirect;
69 port_in_redirect off;
70 }
71
72 location /i/ {
73 alias %%TESTDIR%%/;
74 }
75 }
76
77 server {
78 listen 127.0.0.1:8080 http2;
79 server_name off;
80
81 location / { }
82
83 location /auto/ {
84 proxy_pass http://127.0.0.1:8080;
85 }
86
87 location "/auto sp/" {
88 proxy_pass http://127.0.0.1:8080;
89 }
90
91 location '/auto "#%<>?\^`{|}/' {
92 proxy_pass http://127.0.0.1:8080;
93 }
94
95 location /return301 {
96 return 301 /redirect;
97 }
98
99 location /i/ {
100 alias %%TESTDIR%%/;
101 }
102 }
103 }
104
105 EOF
106
107 mkdir($t->testdir() . '/dir');
108 mkdir($t->testdir() . '/dir sp');
109
110 $t->run()->plan(23);
111
112 ###############################################################################
113
114 my $p = port(8080);
115
116 like(get('on', '/dir'), qr!Location: http://on:$p/dir/\x0d?$!m, 'directory');
117 like(get('on', '/i/dir'), qr!Location: http://on:$p/i/dir/\x0d?$!m,
118 'directory alias');
119
120 TODO: {
121 local $TODO = 'not yet' unless $t->has_version('1.21.0');
122
123 like(get('on', '/dir%20sp'), qr!Location: http://on:$p/dir%20sp/\x0d?$!m,
124 'directory escaped');
125 like(get('on', '/dir%20sp?a=b'),
126 qr!Location: http://on:$p/dir%20sp/\?a=b\x0d?$!m,
127 'directory escaped args');
128
129 }
130
131 like(get('on', '/auto'), qr!Location: http://on:$p/auto/\x0d?$!m, 'auto');
132 like(get('on', '/auto?a=b'), qr!Location: http://on:$p/auto/\?a=b\x0d?$!m,
133 'auto args');
134
135 TODO: {
136 local $TODO = 'not yet' unless $t->has_version('1.21.0');
137
138 like(get('on', '/auto%20sp'), qr!Location: http://on:$p/auto%20sp/\x0d?$!m,
139 'auto escaped');
140 like(get('on', '/auto%20sp?a=b'),
141 qr!Location: http://on:$p/auto%20sp/\?a=b\x0d?$!m,
142 'auto escaped args');
143
144 }
145
146 like(get('on', '/return301'), qr!Location: http://on:$p/redirect\x0d?$!m,
147 'return');
148
149 like(get('host', '/return301/name'), qr!Location: http://on:$p/redirect\x0d?!m,
150 'server_name_in_redirect on');
151 like(get('host', '/return301'), qr!Location: http://host:$p/redirect\x0d?$!m,
152 'server_name_in_redirect off - using host');
153 my $ph = IO::Socket::INET->new("127.0.0.1:$p")->peerhost();
154 like(get('.', '/return301'), qr!Location: http://$ph:$p/redirect\x0d?$!m,
155 'invalid host - using local sockaddr');
156 like(get('host', '/return301/port'), qr!Location: http://host/redirect\x0d?$!m,
157 'port_in_redirect off');
158
159 like(get('off', '/dir'), qr!Location: /dir/\x0d?$!m, 'off directory');
160 like(get('off', '/i/dir'), qr!Location: /i/dir/\x0d?$!m, 'off directory alias');
161
162 TODO: {
163 local $TODO = 'not yet' unless $t->has_version('1.21.0');
164
165 like(get('off', '/dir%20sp'), qr!Location: /dir%20sp/\x0d?$!m,
166 'off directory escaped');
167 like(get('off', '/dir%20sp?a=b'), qr!Location: /dir%20sp/\?a=b\x0d?$!m,
168 'off directory escaped args');
169
170 }
171
172 like(get('off', '/auto'), qr!Location: /auto/\x0d?$!m, 'off auto');
173 like(get('off', '/auto?a=b'), qr!Location: /auto/\?a=b\x0d?$!m,
174 'off auto args');
175
176 TODO: {
177 local $TODO = 'not yet' unless $t->has_version('1.21.0');
178
179 like(get('off', '/auto%20sp'), qr!Location: /auto%20sp/\x0d?$!m,
180 'auto escaped');
181 like(get('off', '/auto%20sp?a=b'), qr!Location: /auto%20sp/\?a=b\x0d?$!m,
182 'auto escaped args');
183
184 }
185
186 like(get('off', '/return301'), qr!Location: /redirect\x0d?$!m, 'off return');
187
188 # per RFC 3986, these characters are not allowed unescaped:
189 # %00-%1F, %7F-%FF, " ", """, "<", ">", "\", "^", "`", "{", "|", "}"
190 # additionally, all characters in ESCAPE_URI: "?", "%", "#"
191
192 SKIP: {
193 skip 'win32', 1 if $^O eq 'MSWin32';
194
195 TODO: {
196 local $TODO = 'not yet' unless $t->has_version('1.21.1');
197
198 like(get('off', '/auto%20%22%23%25%3C%3E%3F%5C%5E%60%7B%7C%7D'),
199 qr!Location: /auto%20%22%23%25%3C%3E%3F%5C%5E%60%7B%7C%7D/\x0d?$!m,
200 'auto escaped strict');
201
202 }
203
204 }
205
206 ###############################################################################
207
208 sub get {
209 my ($host, $uri) = @_;
210
211 my $s = Test::Nginx::HTTP2->new();
212 my $sid = $s->new_stream({ host => $host, path => $uri });
213 my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
214
215 my ($frame) = grep { $_->{type} eq "HEADERS" } @$frames;
216 return 'Location: ' . $frame->{headers}->{'location'};
217 }
218
219 ###############################################################################