# HG changeset patch # User Maxim Dounin # Date 1299249297 -10800 # Node ID 2178954eee5d8aab21f44006cc78029e2672629d # Parent b714d6df958cfce375390d98d4de58a1bb935b36 Tests: add tests for rewrite escaping problems. diff --git a/rewrite_unescape.t b/rewrite_unescape.t new file mode 100644 --- /dev/null +++ b/rewrite_unescape.t @@ -0,0 +1,164 @@ +#!/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%% + +master_process off; +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 aproach 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); +} + +###############################################################################