blob: 490eda6a100d47bb794ddf2310daa0544362d65e [file] [log] [blame]
#!/usr/bin/perl
# (C) Maxim Dounin
# Tests for proxy X-Accel-Redirect functionality.
###############################################################################
use warnings;
use strict;
use Test::More;
BEGIN { use FindBin; chdir($FindBin::Bin); }
use lib 'lib';
use Test::Nginx;
###############################################################################
select STDERR; $| = 1;
select STDOUT; $| = 1;
my $t = Test::Nginx->new()->has(qw/http proxy rewrite/)->plan(16);
$t->write_file_expand('nginx.conf', <<'EOF');
%%TEST_GLOBALS%%
daemon off;
events {
}
http {
%%TEST_GLOBALS_HTTP%%
server {
listen 127.0.0.1:8080;
server_name localhost;
# catch safe and unhandled unsafe URIs,
# bypassed with redirect to named location
if ($upstream_http_x_accel_redirect) {
return 200 "xar: $upstream_http_x_accel_redirect uri: $uri
method: $request_method";
}
location /proxy {
proxy_pass http://127.0.0.1:8080/return-xar;
}
location /return-xar {
add_header X-Accel-Redirect $arg_xar;
# this headers will be preserved on
# X-Accel-Redirect
add_header Content-Type text/blah;
add_header Set-Cookie blah=blah;
add_header Content-Disposition attachment;
add_header Cache-Control no-cache;
add_header Expires fake;
add_header Accept-Ranges parrots;
# others won't be
add_header Something other;
return 204;
}
location @named {
return 200 "named xar: $upstream_http_x_accel_redirect uri: $uri";
}
}
}
EOF
$t->run();
###############################################################################
my $r = http_get('/proxy?xar=/index.html');
like($r, qr/xar: \/index.html uri: \/index.html/, 'X-Accel-Redirect works');
like($r, qr/^Content-Type: text\/blah/m, 'Content-Type preserved');
like($r, qr/^Set-Cookie: blah=blah/m, 'Set-Cookie preserved');
like($r, qr/^Content-Disposition: attachment/m, 'Content-Disposition preserved');
like($r, qr/^Cache-Control: no-cache/m, 'Cache-Control preserved');
like($r, qr/^Expires: fake/m, 'Expires preserved');
like($r, qr/^Accept-Ranges: parrots/m, 'Accept-Ranges preserved');
unlike($r, qr/^Something/m, 'other headers stripped');
like(http_post('/proxy?xar=/index.html'), qr/method: GET/,
'X-Accel-Redirect method name');
# escaped characters
like(http_get('/proxy?xar=/foo?bar'), qr/200 OK.*xar: \/foo\?bar/s,
'X-Accel-Redirect value unchanged');
unlike(http_get('/proxy?xar=..'), qr/200 OK/,
'X-Accel-Redirect unsafe dotdot');
unlike(http_get('/proxy?xar=../foo'), qr/200 OK/,
'X-Accel-Redirect unsafe dotdotsep');
unlike(http_get('/proxy?xar=/foo/..'), qr/200 OK/,
'X-Accel-Redirect unsafe sepdotdot');
unlike(http_get('/proxy?xar=/foo/.%2e'), qr/200 OK/,
'X-Accel-Redirect unsafe unescaped');
like(http_get('/proxy?xar=/foo%20bar'), qr/uri: \/foo bar/,
'X-Accel-Redirect unescaped');
like(http_get('/proxy?xar=@named'),
qr!200 OK.*named xar: \@named uri: /proxy!s, 'in named location');
###############################################################################
sub http_post {
my ($url) = @_;
http(<<EOF);
POST $url HTTP/1.0
Host: localhost
EOF
}
###############################################################################