| #!/usr/bin/perl | |
| # (C) Maxim Dounin | |
| # Tests for escaping/unescaping in rewrite module. | |
| ############################################################################### | |
| 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 rewrite/)->plan(9) | |
| ->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; | |
| location /t1 { | |
| rewrite ^ $arg_r? redirect; | |
| } | |
| location /t2 { | |
| rewrite ^ http://example.com$request_uri? redirect; | |
| } | |
| location /t3 { | |
| rewrite ^ http://example.com$uri redirect; | |
| } | |
| location /t4 { | |
| rewrite ^(.*) http://example.com$1 redirect; | |
| } | |
| location /t5 { | |
| rewrite ^ http://example.com/blah%20%3Fblah redirect; | |
| } | |
| location /t6 { | |
| rewrite ^ http://example.com/blah%20%2Fblah redirect; | |
| } | |
| } | |
| } | |
| EOF | |
| mkdir($t->testdir() . '/directory'); | |
| $t->run(); | |
| ############################################################################### | |
| # Some rewrites and expected (?) behaviour | |
| # | |
| # /t1?r=http%3A%2F%2Fexample.com%2F%3Ffrom | |
| # rewrite ^ $arg_r? redirect; | |
| # expected: http://example.com/?from | |
| # got: http://example.com/?from | |
| # | |
| # /t1?r=http%3A%2F%2Fexample.com%0D%0Asplit | |
| # rewrite ^ $arg_r? redirect; | |
| # expected: http://example.com%0D%0Asplit | |
| # got: http://example.com%0D%0Asplit | |
| # | |
| # /t1?r=http%3A%2F%2Fexample.com%2F%3Ffrom%3Dblah | |
| # rewrite ^ $arg_r? redirect; | |
| # expected: http://example.com/?from=blah | |
| # got: http://example.com/?from%3Dblah | |
| # | |
| # /blah%3Fblah | |
| # rewrite ^ http://example.com$request_uri? redirect; | |
| # expected: http://example.com/blah%3Fblah | |
| # got: http://example.com/blah?blah | |
| # | |
| # /blah%3Fblah | |
| # rewrite ^ http://example.com$uri redirect; | |
| # expected: http://example.com/blah%3Fblah | |
| # got: http://example.com/blah?blah | |
| # | |
| # /blah%3Fblah | |
| # rewrite ^(.*) http://example.com$1 redirect; | |
| # expected: http://example.com/blah%3Fblah | |
| # got: http://example.com/blah?blah | |
| # | |
| # / | |
| # rewrite ^ http://example.com/blah%3Fblah redirect; | |
| # expected: http://example.com/blah%3Fblah | |
| # got: http://example.com/blah?blah | |
| # | |
| location('/t1?r=http%3A%2F%2Fexample.com%2F%3Ffrom', | |
| 'http://example.com/?from', 'escaped argument'); | |
| location('/t1?r=http%3A%2F%2Fexample.com%0D%0Asplit', | |
| 'http://example.com%0D%0Asplit', 'escaped argument header splitting'); | |
| TODO: { | |
| local $TODO = 'not yet'; | |
| # Fixing this cases will require major changes to the whole approach and | |
| # likely to break some currently working cases. On the other hand, current | |
| # behaviour is far from acceptable. Should be carefully thought. | |
| location('/t1?r=http%3A%2F%2Fexample.com%2F%3Ffrom%3Dblah', | |
| 'http://example.com/?from=blah', 'escaped argument with complex query'); | |
| location('/t2/blah%20%3Fblah', | |
| 'http://example.com/t2/blah%20%3Fblah', 'escaped $request_uri'); | |
| location('/t3/blah%20%3Fblah', | |
| 'http://example.com/t3/blah%20%3Fblah', 'escaped $uri'); | |
| location('/t4/blah%20%3Fblah', | |
| 'http://example.com/t4/blah%20%3Fblah', 'escaped $1'); | |
| location('/t5', | |
| 'http://example.com/blah%20%3Fblah', 'escaped static'); | |
| location('/t5?arg=blah', | |
| 'http://example.com/blah%20%3Fblah?arg=blah', | |
| 'escaped static with argument'); | |
| location('/t6', | |
| 'http://example.com/blah%20%2Fblah', 'escaped static slash'); | |
| } | |
| ############################################################################### | |
| sub location { | |
| my ($url, $value, $name) = @_; | |
| my $data = http_get($url); | |
| if ($data !~ qr!^Location: (.*?)\x0d?$!ms) { | |
| fail($name); | |
| return; | |
| } | |
| my $location = $1; | |
| is($location, $value, $name); | |
| } | |
| ############################################################################### |