|  | #!/usr/bin/perl | 
|  |  | 
|  | # (C) Maxim Dounin | 
|  |  | 
|  | # Tests for 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(19) | 
|  | ->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 / { | 
|  | rewrite ^ http://example.com/ redirect; | 
|  | } | 
|  |  | 
|  | location /add { | 
|  | rewrite ^ http://example.com/?c=d redirect; | 
|  | } | 
|  |  | 
|  | location /no { | 
|  | rewrite ^ http://example.com/?c=d? redirect; | 
|  | } | 
|  |  | 
|  | location /return204 { | 
|  | return 204; | 
|  | } | 
|  |  | 
|  | location /return200 { | 
|  | return 200; | 
|  | } | 
|  |  | 
|  | location /return405 { | 
|  | return 405; | 
|  | } | 
|  |  | 
|  | location /error404return405 { | 
|  | error_page 404 /return405; | 
|  | return 404; | 
|  | } | 
|  |  | 
|  | location /error405return204 { | 
|  | error_page 405 /return204; | 
|  | return 405; | 
|  | } | 
|  |  | 
|  | location /error405return200 { | 
|  | error_page 405 /return200; | 
|  | return 405; | 
|  | } | 
|  |  | 
|  | location /return200text { | 
|  | return 200 "text"; | 
|  | } | 
|  |  | 
|  | location /return404text { | 
|  | return 404 "text"; | 
|  | } | 
|  |  | 
|  | location /return302text { | 
|  | return 302 "text"; | 
|  | } | 
|  |  | 
|  | location /error405return200text { | 
|  | error_page 405 /return200text; | 
|  | return 405; | 
|  | } | 
|  |  | 
|  | location /error302return200text { | 
|  | error_page 302 /return200text; | 
|  | return 302 "text"; | 
|  | } | 
|  |  | 
|  | location /error405return302text { | 
|  | error_page 405 /return302text; | 
|  | return 405; | 
|  | } | 
|  |  | 
|  | location /error405rewrite { | 
|  | error_page 405 /; | 
|  | return 405; | 
|  | } | 
|  |  | 
|  | location /error405directory { | 
|  | error_page 405 /directory; | 
|  | return 405; | 
|  | } | 
|  |  | 
|  | location /directory { | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | EOF | 
|  |  | 
|  | mkdir($t->testdir() . '/directory'); | 
|  |  | 
|  | $t->run(); | 
|  |  | 
|  | ############################################################################### | 
|  |  | 
|  | like(http_get('/'), qr!^Location: http://example.com/\x0d?$!ms, 'simple'); | 
|  | like(http_get('/?a=b'), qr!^Location: http://example.com/\?a=b\x0d?$!ms, | 
|  | 'simple with args'); | 
|  | like(http_get('/add'), qr!^Location: http://example.com/\?c=d\x0d?$!ms, | 
|  | 'add args'); | 
|  |  | 
|  | like(http_get('/add?a=b'), qr!^Location: http://example.com/\?c=d&a=b\x0d?$!ms, | 
|  | 'add args with args'); | 
|  |  | 
|  | like(http_get('/no?a=b'), qr!^Location: http://example.com/\?c=d\x0d?$!ms, | 
|  | 'no args with args'); | 
|  |  | 
|  | like(http_get('/return204'), qr!204 No Content!, 'return 204'); | 
|  | like(http_get('/return200'), qr!200 OK!, 'return 200'); | 
|  | like(http_get('/return405'), qr!HTTP/1.1 405.*body!ms, 'return 405'); | 
|  |  | 
|  | like(http_get('/error404return405'), qr!HTTP/1.1 404!, 'error 404 return 405'); | 
|  |  | 
|  | TODO: { | 
|  | local $TODO = 'not yet'; | 
|  |  | 
|  | # status code should be 405, and entity body is expected (vs. normal 204 | 
|  | # replies which doesn't expect to have body); use HTTP/1.1 for test | 
|  | # to make problem clear | 
|  |  | 
|  | my $r = http(<<EOF); | 
|  | GET /error405return204 HTTP/1.1 | 
|  | Host: localhost | 
|  | Connection: close | 
|  |  | 
|  | EOF | 
|  |  | 
|  | like($r, qr/HTTP\/1.1 405.*(Content-Length|\x0d\0a0\x0d\x0a)/ms, | 
|  | 'error 405 return 204'); | 
|  |  | 
|  | # the same test, but with return 200.  this doesn't have special | 
|  | # handling and returns builtin error page body (the same problem as | 
|  | # in /error405return200text below) | 
|  |  | 
|  | like(http_get('/error405return200'), qr/HTTP\/1.1 405(?!.*body)/ms, | 
|  | 'error 405 return 200'); | 
|  |  | 
|  | } | 
|  |  | 
|  | # tests involving return with two arguments, as introduced in | 
|  | # 0.8.42 | 
|  |  | 
|  | like(http_get('/return200text'), qr!text\z!, 'return 200 text'); | 
|  | like(http_get('/return404text'), qr!text\z!, 'return 404 text'); | 
|  |  | 
|  | TODO: { | 
|  | local $TODO = 'not yet'; | 
|  |  | 
|  | like(http_get('/error405return200text'), qr!HTTP/1.1 405.*text\z!ms, | 
|  | 'error 405 to return 200 text'); | 
|  |  | 
|  | } | 
|  |  | 
|  | # return 302 is somewhat special: it adds Location header instead of | 
|  | # body text.  additionally it doesn't sent reply directly (as it's done for | 
|  | # other returns since 0.8.42) but instead returns NGX_HTTP_* code | 
|  |  | 
|  | like(http_get('/return302text'), qr!HTTP/1.1 302.*Location: text!ms, | 
|  | 'return 302 text'); | 
|  |  | 
|  | TODO: { | 
|  | local $TODO = 'not yet'; | 
|  |  | 
|  | like(http_get('/error302return200text'), | 
|  | qr!HTTP/1.1 302.*Location: text.*text\z!ms, | 
|  | 'error 302 return 200 text'); | 
|  |  | 
|  | } | 
|  |  | 
|  | TODO: { | 
|  | local $TODO = 'not yet'; | 
|  |  | 
|  | # in contrast to other return's this shouldn't preserve original status code | 
|  | # from error, and the same applies to "rewrite ... redirect" as an error | 
|  | # handler; both should in line with e.g. directory redirect as well | 
|  |  | 
|  | like(http_get('/error405return302text'), | 
|  | qr!HTTP/1.1 302.*Location: text!ms, | 
|  | 'error 405 return 302 text'); | 
|  |  | 
|  | like(http_get('/error405rewrite'), | 
|  | qr!HTTP/1.1 302.*Location: http://example.com/!ms, | 
|  | 'error 405 rewrite redirect'); | 
|  |  | 
|  | } | 
|  |  | 
|  | like(http_get('/error405directory'), | 
|  | qr!HTTP/1.1 301.*Location: http://!ms, | 
|  | 'error 405 directory redirect'); | 
|  |  | 
|  | ############################################################################### |