changeset 148:b714d6df958c

Tests: rename some tests for better sorting. Use underscore instead of dash. Addtionally, rename some tests to better match "module" + "details" scheme used: use "http_" prefix for http core module tests, use "mail_" prefix for mail module tests.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 04 Mar 2011 16:07:15 +0300
parents fd865ada95c8
children 2178954eee5d
files expect-100-continue.t fastcgi-cache.t fastcgi_cache.t gzip-flush.t gzip_flush.t http-error-page.t http-location.t http-server-name.t http_error_page.t http_expect_100_continue.t http_location.t http_server_name.t imap.t limit-req.t limit_req.t mail_imap.t mail_pop3.t mail_smtp.t mail_smtp_greeting_delay.t mail_smtp_xclient.t memcached-fake.t memcached_fake.t not-modified.t not_modified.t perl-gzip.t perl_gzip.t pop3.t proxy-cache.t proxy-chunked.t proxy-noclose.t proxy-store.t proxy-xar.t proxy_cache.t proxy_chunked.t proxy_noclose.t proxy_store.t proxy_xar.t random-index.t random_index.t range-flv.t range_flv.t smtp-greeting-delay.t smtp-xclient.t smtp.t ssi-include-big.t ssi-waited.t ssi_include_big.t ssi_waited.t
diffstat 48 files changed, 2603 insertions(+), 2603 deletions(-) [+]
line wrap: on
line diff
--- a/expect-100-continue.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for Expect: 100-continue support.
-
-###############################################################################
-
-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/)->plan(2);
-
-$t->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 / {
-            proxy_pass http://localhost:8080/local;
-        }
-        location /local {
-        }
-    }
-}
-
-EOF
-
-$t->run();
-
-###############################################################################
-
-like(http_100_request('/', '1.1'), qr/100/, 'expect 100 continue');
-
-# From RFC 2616, 8.2.3 Use of the 100 (Continue) Status:
-#
-#      - An origin server SHOULD NOT send a 100 (Continue) response if
-#        the request message does not include an Expect request-header
-#        field with the "100-continue" expectation, and MUST NOT send a
-#        100 (Continue) response if such a request comes from an HTTP/1.0
-#        (or earlier) client.
-
-unlike(http_100_request('/', '1.0'), qr/100/, 'no 100 continue via http 1.0');
-
-###############################################################################
-
-sub http_100_request {
-	my ($url, $version) = @_;
-	my $r = http(<<EOF);
-POST $url HTTP/$version
-Host: localhost
-Expect: 100-continue
-Content-Length: 0
-Connection: close
-
-EOF
-}
-
-###############################################################################
--- a/fastcgi-cache.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Test for fastcgi backend with cache.
-
-###############################################################################
-
-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;
-
-eval { require FCGI; };
-plan(skip_all => 'FCGI not installed') if $@;
-
-my $t = Test::Nginx->new()->has(qw/http fastcgi cache/)->plan(5)
-	->write_file_expand('nginx.conf', <<'EOF');
-
-%%TEST_GLOBALS%%
-
-master_process off;
-daemon         off;
-
-events {
-}
-
-http {
-    %%TEST_GLOBALS_HTTP%%
-
-    fastcgi_cache_path   %%TESTDIR%%/cache  levels=1:2
-                         keys_zone=NAME:10m;
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  localhost;
-
-        location / {
-            fastcgi_pass 127.0.0.1:8081;
-            fastcgi_param REQUEST_URI $request_uri;
-            fastcgi_cache NAME;
-            fastcgi_cache_key $request_uri;
-            fastcgi_cache_valid 302 1m;
-        }
-    }
-}
-
-EOF
-
-$t->run_daemon(\&fastcgi_daemon);
-$t->run();
-
-###############################################################################
-
-like(http_get('/'), qr/SEE-THIS/, 'fastcgi request');
-like(http_get('/'), qr/SEE-THIS/, 'fastcgi request cached');
-
-unlike(http_head('/'), qr/SEE-THIS/, 'no data in cached HEAD');
-
-like(http_get('/stderr'), qr/SEE-THIS/, 'large stderr handled');
-like(http_get('/stderr'), qr/SEE-THIS/, 'large stderr cached');
-
-###############################################################################
-
-sub fastcgi_daemon {
-	my $socket = FCGI::OpenSocket('127.0.0.1:8081', 5);
-	my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV,
-		$socket);
-
-	my $count;
-	while( $request->Accept() >= 0 ) {
-		$count++;
-
-		if ($ENV{REQUEST_URI} eq '/stderr') {
-			warn "sample stderr text" x 512;
-		}
-		
-		print <<EOF;
-Location: http://127.0.0.1:8080/redirect
-Content-Type: text/html
-
-SEE-THIS
-$count
-EOF
-	}
-
-	FCGI::CloseSocket($socket);
-}
-
-###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fastcgi_cache.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Test for fastcgi backend with cache.
+
+###############################################################################
+
+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;
+
+eval { require FCGI; };
+plan(skip_all => 'FCGI not installed') if $@;
+
+my $t = Test::Nginx->new()->has(qw/http fastcgi cache/)->plan(5)
+	->write_file_expand('nginx.conf', <<'EOF');
+
+%%TEST_GLOBALS%%
+
+master_process off;
+daemon         off;
+
+events {
+}
+
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    fastcgi_cache_path   %%TESTDIR%%/cache  levels=1:2
+                         keys_zone=NAME:10m;
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  localhost;
+
+        location / {
+            fastcgi_pass 127.0.0.1:8081;
+            fastcgi_param REQUEST_URI $request_uri;
+            fastcgi_cache NAME;
+            fastcgi_cache_key $request_uri;
+            fastcgi_cache_valid 302 1m;
+        }
+    }
+}
+
+EOF
+
+$t->run_daemon(\&fastcgi_daemon);
+$t->run();
+
+###############################################################################
+
+like(http_get('/'), qr/SEE-THIS/, 'fastcgi request');
+like(http_get('/'), qr/SEE-THIS/, 'fastcgi request cached');
+
+unlike(http_head('/'), qr/SEE-THIS/, 'no data in cached HEAD');
+
+like(http_get('/stderr'), qr/SEE-THIS/, 'large stderr handled');
+like(http_get('/stderr'), qr/SEE-THIS/, 'large stderr cached');
+
+###############################################################################
+
+sub fastcgi_daemon {
+	my $socket = FCGI::OpenSocket('127.0.0.1:8081', 5);
+	my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV,
+		$socket);
+
+	my $count;
+	while( $request->Accept() >= 0 ) {
+		$count++;
+
+		if ($ENV{REQUEST_URI} eq '/stderr') {
+			warn "sample stderr text" x 512;
+		}
+		
+		print <<EOF;
+Location: http://127.0.0.1:8080/redirect
+Content-Type: text/html
+
+SEE-THIS
+$count
+EOF
+	}
+
+	FCGI::CloseSocket($socket);
+}
+
+###############################################################################
--- a/gzip-flush.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for gzip filter module.
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-
-BEGIN { use FindBin; chdir($FindBin::Bin); }
-
-use lib 'lib';
-use Test::Nginx qw/ :DEFAULT :gzip /;
-
-###############################################################################
-
-select STDERR; $| = 1;
-select STDOUT; $| = 1;
-
-my $t = Test::Nginx->new()->has(qw/http gzip perl/)->plan(2)
-	->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;
-
-        gzip on;
-        gzip_min_length 0;
-
-        location / {
-            perl 'sub {
-                my $r = shift;
-                $r->send_http_header("text/html");
-                return OK if $r->header_only;
-                $r->print("DA");
-                $r->flush();
-                $r->flush();
-                $r->print("TA");
-                return OK;
-            }';
-        }
-    }
-}
-
-EOF
-
-$t->run();
-
-###############################################################################
-
-like(http_get('/'), qr/DATA/, 'request with flush');
-
-TODO: {
-local $TODO = 'not yet';
-
-# gzip filter doesn't properly handle empty flush buffers, see
-# http://nginx.org/pipermail/nginx/2010-November/023693.html
-
-http_gzip_like(http_gzip_request('/'), qr/DATA/, 'gzip request with flush');
-
-}
-
-###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gzip_flush.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,78 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for gzip filter module.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx qw/ :DEFAULT :gzip /;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+my $t = Test::Nginx->new()->has(qw/http gzip perl/)->plan(2)
+	->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;
+
+        gzip on;
+        gzip_min_length 0;
+
+        location / {
+            perl 'sub {
+                my $r = shift;
+                $r->send_http_header("text/html");
+                return OK if $r->header_only;
+                $r->print("DA");
+                $r->flush();
+                $r->flush();
+                $r->print("TA");
+                return OK;
+            }';
+        }
+    }
+}
+
+EOF
+
+$t->run();
+
+###############################################################################
+
+like(http_get('/'), qr/DATA/, 'request with flush');
+
+TODO: {
+local $TODO = 'not yet';
+
+# gzip filter doesn't properly handle empty flush buffers, see
+# http://nginx.org/pipermail/nginx/2010-November/023693.html
+
+http_gzip_like(http_gzip_request('/'), qr/DATA/, 'gzip request with flush');
+
+}
+
+###############################################################################
--- a/http-error-page.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for error_page directive.
-
-###############################################################################
-
-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(7)
-	->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 /redirect200 {
-            error_page 404 =200 http://example.com/;
-            return 404;
-        }
-
-        location /redirect497 {
-            # 497 implies implicit status code change
-            error_page 497 https://example.com/;
-            return 497;
-        }
-
-        location /error302redirect {
-            error_page 302 http://example.com/;
-            return 302 "first";
-        }
-
-        location /error302return302text {
-            error_page 302 /return302text;
-            return 302 "first";
-        }
-
-        location /return302text {
-            return 302 "http://example.com/";
-        }
-
-        location /error302rewrite {
-            error_page 302 /rewrite;
-            return 302 "first";
-        }
-
-        location /rewrite {
-            rewrite ^ http://example.com/;
-        }
-
-        location /error302directory {
-            error_page 302 /directory;
-            return 302 "first";
-        }
-
-        location /directory {
-        }
-
-        location /error302auto {
-            error_page 302 /auto;
-            return 302 "first";
-        }
-
-        location /auto/ {
-            proxy_pass http://127.0.0.1:8081;
-        }
-    }
-}
-
-EOF
-
-mkdir($t->testdir() . '/directory');
-
-$t->run();
-
-###############################################################################
-
-# tests for error_page status code change for redirects. problems
-# introduced in 0.8.53 and fixed in 0.9.5.
-
-like(http_get('/redirect200'), qr!HTTP!, 'redirect 200');
-like(http_get('/redirect497'), qr!HTTP/1.1 302!, 'redirect 497');
-
-TODO: {
-local $TODO = 'not yet';
-
-# various tests to see if old location cleared if we happen to redirect
-# again in error_page 302
-
-like(http_get('/error302redirect'),
-	qr{HTTP/1.1 302(?!.*Location: first).*Location: http://example.com/}ms,
-	'error 302 redirect - old location cleared');
-
-like(http_get('/error302return302text'),
-	qr{HTTP/1.1 302(?!.*Location: first).*Location: http://example.com/}ms,
-	'error 302 return 302 text - old location cleared');
-
-like(http_get('/error302rewrite'),
-	qr{HTTP/1.1 302(?!.*Location: first).*Location: http://example.com/}ms,
-	'error 302 rewrite - old location cleared');
-
-like(http_get('/error302directory'),
-	qr{HTTP/1.1 301(?!.*Location: first).*Location: http://}ms,
-	'error 302 directory redirect - old location cleared');
-
-like(http_get('/error302auto'),
-	qr{HTTP/1.1 301(?!.*Location: first).*Location: http://}ms,
-	'error 302 auto redirect - old location cleared');
-
-}
-
-###############################################################################
--- a/http-location.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for location selection.
-
-###############################################################################
-
-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(8)
-	->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 = / {
-            add_header X-Location exactlyroot;
-            return 204;
-        }
-
-        location / {
-            add_header X-Location root;
-            return 204;
-        }
-
-        location ^~ /images/ {
-            add_header X-Location images;
-            return 204;
-        }
-
-        location ~* \.(gif|jpg|jpeg)$ {
-            add_header X-Location regex;
-            return 204;
-        }
-
-        location ~ casefull {
-            add_header X-Location casefull;
-            return 204;
-        }
-    }
-}
-
-EOF
-
-$t->run();
-
-###############################################################################
-
-like(http_get('/'), qr/X-Location: exactlyroot/, 'exactlyroot');
-like(http_get('/x'), qr/X-Location: root/, 'root');
-like(http_get('/images/t.gif'), qr/X-Location: images/, 'images');
-like(http_get('/t.gif'), qr/X-Location: regex/, 'regex');
-like(http_get('/t.GIF'), qr/X-Location: regex/, 'regex with mungled case');
-like(http_get('/casefull/t.gif'), qr/X-Location: regex/, 'first regex wins');
-like(http_get('/casefull/'), qr/X-Location: casefull/, 'casefull regex');
-like(http_get('/CASEFULL/'), qr/X-Location: root/,
-     'casefull regex do not match wrong case');
-
-###############################################################################
--- a/http-server-name.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for server_name selection.
-
-###############################################################################
-
-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 / {
-            add_header X-Server $server_name;
-            return 204;
-        }
-    }
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  www.example.com;
-
-        location / {
-            add_header X-Server $server_name;
-            return 204;
-        }
-    }
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  ~^EXAMPLE\.COM$;
-
-        location / {
-            add_header X-Server $server_name;
-            return 204;
-        }
-    }
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  ~^(?P<name>.+)\Q.example.com\E$;
-
-        location / {
-            add_header X-Server $server_name;
-            add_header X-Match  $name;
-            return 204;
-        }
-    }
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  "~^(?<name>www\p{N}+)\.example\.com$";
-
-        location / {
-            add_header X-Server $server_name;
-            add_header X-Match  $name;
-            return 204;
-        }
-    }
-}
-
-EOF
-
-$t->run();
-
-###############################################################################
-
-sub http_server($) {
-	my ($host) = @_;
-	return http(<<EOF);
-GET / HTTP/1.0
-Host: $host
-
-EOF
-}
-
-###############################################################################
-
-like(http_server('xxx'), qr/X-Server: localhost/, 'default');
-
-like(http_server('www.example.com'), qr/\QX-Server: www.example.com/,
-	'www.example.com');
-like(http_server('WWW.EXAMPLE.COM'), qr/\QX-Server: www.example.com/,
-	'www.example.com uppercase');
-
-like(http_server('example.com'), qr/\QX-Server: ~^EXAMPLE\.COM$/,
-	'example.com regex');
-like(http_server('EXAMPLE.COM'), qr/\QX-Server: ~^EXAMPLE\.COM$/,
-	'example.com regex uppercase');
-
-like(http_server('blah.example.com'), qr/X-Match: blah/,
-	'(P<name>.*).example.com named capture');
-like(http_server('BLAH.EXAMPLE.COM'), qr/X-Match: blah/,
-	'(P<name>.*).example.com named capture uppercase');
-
-like(http_server('www01.example.com'), qr/X-Match: www01/,
-	'\p{N} in named capture');
-like(http_server('WWW01.EXAMPLE.COM'), qr/X-Match: www01/,
-	'\p{N} in named capture uppercase');
-
-###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/http_error_page.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,137 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for error_page directive.
+
+###############################################################################
+
+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(7)
+	->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 /redirect200 {
+            error_page 404 =200 http://example.com/;
+            return 404;
+        }
+
+        location /redirect497 {
+            # 497 implies implicit status code change
+            error_page 497 https://example.com/;
+            return 497;
+        }
+
+        location /error302redirect {
+            error_page 302 http://example.com/;
+            return 302 "first";
+        }
+
+        location /error302return302text {
+            error_page 302 /return302text;
+            return 302 "first";
+        }
+
+        location /return302text {
+            return 302 "http://example.com/";
+        }
+
+        location /error302rewrite {
+            error_page 302 /rewrite;
+            return 302 "first";
+        }
+
+        location /rewrite {
+            rewrite ^ http://example.com/;
+        }
+
+        location /error302directory {
+            error_page 302 /directory;
+            return 302 "first";
+        }
+
+        location /directory {
+        }
+
+        location /error302auto {
+            error_page 302 /auto;
+            return 302 "first";
+        }
+
+        location /auto/ {
+            proxy_pass http://127.0.0.1:8081;
+        }
+    }
+}
+
+EOF
+
+mkdir($t->testdir() . '/directory');
+
+$t->run();
+
+###############################################################################
+
+# tests for error_page status code change for redirects. problems
+# introduced in 0.8.53 and fixed in 0.9.5.
+
+like(http_get('/redirect200'), qr!HTTP!, 'redirect 200');
+like(http_get('/redirect497'), qr!HTTP/1.1 302!, 'redirect 497');
+
+TODO: {
+local $TODO = 'not yet';
+
+# various tests to see if old location cleared if we happen to redirect
+# again in error_page 302
+
+like(http_get('/error302redirect'),
+	qr{HTTP/1.1 302(?!.*Location: first).*Location: http://example.com/}ms,
+	'error 302 redirect - old location cleared');
+
+like(http_get('/error302return302text'),
+	qr{HTTP/1.1 302(?!.*Location: first).*Location: http://example.com/}ms,
+	'error 302 return 302 text - old location cleared');
+
+like(http_get('/error302rewrite'),
+	qr{HTTP/1.1 302(?!.*Location: first).*Location: http://example.com/}ms,
+	'error 302 rewrite - old location cleared');
+
+like(http_get('/error302directory'),
+	qr{HTTP/1.1 301(?!.*Location: first).*Location: http://}ms,
+	'error 302 directory redirect - old location cleared');
+
+like(http_get('/error302auto'),
+	qr{HTTP/1.1 301(?!.*Location: first).*Location: http://}ms,
+	'error 302 auto redirect - old location cleared');
+
+}
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/http_expect_100_continue.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for Expect: 100-continue support.
+
+###############################################################################
+
+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/)->plan(2);
+
+$t->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 / {
+            proxy_pass http://localhost:8080/local;
+        }
+        location /local {
+        }
+    }
+}
+
+EOF
+
+$t->run();
+
+###############################################################################
+
+like(http_100_request('/', '1.1'), qr/100/, 'expect 100 continue');
+
+# From RFC 2616, 8.2.3 Use of the 100 (Continue) Status:
+#
+#      - An origin server SHOULD NOT send a 100 (Continue) response if
+#        the request message does not include an Expect request-header
+#        field with the "100-continue" expectation, and MUST NOT send a
+#        100 (Continue) response if such a request comes from an HTTP/1.0
+#        (or earlier) client.
+
+unlike(http_100_request('/', '1.0'), qr/100/, 'no 100 continue via http 1.0');
+
+###############################################################################
+
+sub http_100_request {
+	my ($url, $version) = @_;
+	my $r = http(<<EOF);
+POST $url HTTP/$version
+Host: localhost
+Expect: 100-continue
+Content-Length: 0
+Connection: close
+
+EOF
+}
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/http_location.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,85 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for location selection.
+
+###############################################################################
+
+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(8)
+	->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 = / {
+            add_header X-Location exactlyroot;
+            return 204;
+        }
+
+        location / {
+            add_header X-Location root;
+            return 204;
+        }
+
+        location ^~ /images/ {
+            add_header X-Location images;
+            return 204;
+        }
+
+        location ~* \.(gif|jpg|jpeg)$ {
+            add_header X-Location regex;
+            return 204;
+        }
+
+        location ~ casefull {
+            add_header X-Location casefull;
+            return 204;
+        }
+    }
+}
+
+EOF
+
+$t->run();
+
+###############################################################################
+
+like(http_get('/'), qr/X-Location: exactlyroot/, 'exactlyroot');
+like(http_get('/x'), qr/X-Location: root/, 'root');
+like(http_get('/images/t.gif'), qr/X-Location: images/, 'images');
+like(http_get('/t.gif'), qr/X-Location: regex/, 'regex');
+like(http_get('/t.GIF'), qr/X-Location: regex/, 'regex with mungled case');
+like(http_get('/casefull/t.gif'), qr/X-Location: regex/, 'first regex wins');
+like(http_get('/casefull/'), qr/X-Location: casefull/, 'casefull regex');
+like(http_get('/CASEFULL/'), qr/X-Location: root/,
+     'casefull regex do not match wrong case');
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/http_server_name.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,130 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for server_name selection.
+
+###############################################################################
+
+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 / {
+            add_header X-Server $server_name;
+            return 204;
+        }
+    }
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  www.example.com;
+
+        location / {
+            add_header X-Server $server_name;
+            return 204;
+        }
+    }
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  ~^EXAMPLE\.COM$;
+
+        location / {
+            add_header X-Server $server_name;
+            return 204;
+        }
+    }
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  ~^(?P<name>.+)\Q.example.com\E$;
+
+        location / {
+            add_header X-Server $server_name;
+            add_header X-Match  $name;
+            return 204;
+        }
+    }
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  "~^(?<name>www\p{N}+)\.example\.com$";
+
+        location / {
+            add_header X-Server $server_name;
+            add_header X-Match  $name;
+            return 204;
+        }
+    }
+}
+
+EOF
+
+$t->run();
+
+###############################################################################
+
+sub http_server($) {
+	my ($host) = @_;
+	return http(<<EOF);
+GET / HTTP/1.0
+Host: $host
+
+EOF
+}
+
+###############################################################################
+
+like(http_server('xxx'), qr/X-Server: localhost/, 'default');
+
+like(http_server('www.example.com'), qr/\QX-Server: www.example.com/,
+	'www.example.com');
+like(http_server('WWW.EXAMPLE.COM'), qr/\QX-Server: www.example.com/,
+	'www.example.com uppercase');
+
+like(http_server('example.com'), qr/\QX-Server: ~^EXAMPLE\.COM$/,
+	'example.com regex');
+like(http_server('EXAMPLE.COM'), qr/\QX-Server: ~^EXAMPLE\.COM$/,
+	'example.com regex uppercase');
+
+like(http_server('blah.example.com'), qr/X-Match: blah/,
+	'(P<name>.*).example.com named capture');
+like(http_server('BLAH.EXAMPLE.COM'), qr/X-Match: blah/,
+	'(P<name>.*).example.com named capture uppercase');
+
+like(http_server('www01.example.com'), qr/X-Match: www01/,
+	'\p{N} in named capture');
+like(http_server('WWW01.EXAMPLE.COM'), qr/X-Match: www01/,
+	'\p{N} in named capture uppercase');
+
+###############################################################################
--- a/imap.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for nginx mail imap module.
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-
-use IO::Socket;
-use MIME::Base64;
-use Socket qw/ CRLF /;
-
-BEGIN { use FindBin; chdir($FindBin::Bin); }
-
-use lib 'lib';
-use Test::Nginx;
-use Test::Nginx::IMAP;
-
-###############################################################################
-
-select STDERR; $| = 1;
-select STDOUT; $| = 1;
-
-local $SIG{PIPE} = 'IGNORE';
-
-my $t = Test::Nginx->new()
-	->has(qw/mail imap http rewrite/)->plan(8)
-	->run_daemon(\&Test::Nginx::IMAP::imap_test_daemon)
-	->write_file_expand('nginx.conf', <<'EOF')->run();
-
-%%TEST_GLOBALS%%
-
-master_process off;
-daemon         off;
-
-events {
-}
-
-mail {
-    proxy_pass_error_message  on;
-    auth_http  http://127.0.0.1:8080/mail/auth;
-
-    server {
-        listen     127.0.0.1:8143;
-        protocol   imap;
-    }
-}
-
-http {
-    %%TEST_GLOBALS_HTTP%%
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  localhost;
-
-        location = /mail/auth {
-            set $reply ERROR;
-
-            if ($http_auth_smtp_to ~ example.com) {
-                set $reply OK;
-            }
-
-            set $userpass "$http_auth_user:$http_auth_pass";
-            if ($userpass ~ '^test@example.com:secret$') {
-                set $reply OK;
-            }
-
-            add_header Auth-Status $reply;
-            add_header Auth-Server 127.0.0.1;
-            add_header Auth-Port 8144;
-            add_header Auth-Wait 1;
-            return 204;
-        }
-    }
-}
-
-EOF
-
-###############################################################################
-
-my $s = Test::Nginx::IMAP->new();
-$s->ok('greeting');
-
-# auth plain
-
-$s->send('1 AUTHENTICATE PLAIN ' . encode_base64("\0test\@example.com\0bad", ''));
-$s->check(qr/^\S+ NO/, 'auth plain with bad password');
-
-$s->send('1 AUTHENTICATE PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
-$s->ok('auth plain');
-
-# auth login simple
-
-$s = Test::Nginx::IMAP->new();
-$s->read();
-
-$s->send('1 AUTHENTICATE LOGIN');
-$s->check(qr/\+ VXNlcm5hbWU6/, 'auth login username challenge');
-
-$s->send(encode_base64('test@example.com', ''));
-$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login password challenge');
-
-$s->send(encode_base64('secret', ''));
-$s->ok('auth login simple');
-
-# auth login with username
-
-$s = Test::Nginx::IMAP->new();
-$s->read();
-
-$s->send('1 AUTHENTICATE LOGIN ' . encode_base64('test@example.com', ''));
-$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login with username password challenge');
-
-$s->send(encode_base64('secret', ''));
-$s->ok('auth login with username');
-
-###############################################################################
--- a/limit-req.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for nginx limit_req 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 limit_req/)->plan(5);
-
-$t->write_file_expand('nginx.conf', <<'EOF');
-
-%%TEST_GLOBALS%%
-
-master_process off;
-daemon         off;
-
-events {
-}
-
-http {
-    %%TEST_GLOBALS_HTTP%%
-
-    limit_req_zone  $binary_remote_addr  zone=one:10m   rate=1r/s;
-    limit_req_zone  $binary_remote_addr  zone=long:10m  rate=1r/s;
-    limit_req_zone  $binary_remote_addr  zone=fast:10m  rate=1000r/s;
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  localhost;
-        location / {
-            limit_req    zone=one  burst=1  nodelay;
-        }
-        location /long {
-            limit_req    zone=long  burst=5;
-        }
-        location /fast {
-            limit_req    zone=fast  burst=1;
-        }
-    }
-}
-
-EOF
-
-$t->write_file('test1.html', 'XtestX');
-$t->write_file('long.html', "1234567890\n" x (1 << 16));
-$t->write_file('fast.html', 'XtestX');
-$t->run();
-
-###############################################################################
-
-like(http_get('/test1.html'), qr/^HTTP\/1.. 200 /m, 'request');
-http_get('/test1.html');
-like(http_get('/test1.html'), qr/^HTTP\/1.. 503 /m, 'request rejected');
-http_get('/test1.html');
-http_get('/test1.html');
-
-# Second request will be delayed by limit_req, make sure it isn't truncated.
-# The bug only manifests itself if buffer will be filled, so sleep for a while
-# before reading response.
-
-my $l1 = length(http_get('/long.html'));
-my $l2 = length(http_get('/long.html', sleep => 1.1));
-is($l2, $l1, 'delayed big request not truncated');
-
-# make sure rejected requests are not counted, and access is again allowed
-# after 1/rate seconds
-
-like(http_get('/test1.html'), qr/^HTTP\/1.. 200 /m, 'rejects not counted');
-
-# make sure negative excess values are handled properly
-
-http_get('/fast.html');
-select undef, undef, undef, 0.1;
-like(http_get('/fast.html'), qr/^HTTP\/1.. 200 /m, 'negative excess');
-
-###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/limit_req.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,92 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for nginx limit_req 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 limit_req/)->plan(5);
+
+$t->write_file_expand('nginx.conf', <<'EOF');
+
+%%TEST_GLOBALS%%
+
+master_process off;
+daemon         off;
+
+events {
+}
+
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    limit_req_zone  $binary_remote_addr  zone=one:10m   rate=1r/s;
+    limit_req_zone  $binary_remote_addr  zone=long:10m  rate=1r/s;
+    limit_req_zone  $binary_remote_addr  zone=fast:10m  rate=1000r/s;
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  localhost;
+        location / {
+            limit_req    zone=one  burst=1  nodelay;
+        }
+        location /long {
+            limit_req    zone=long  burst=5;
+        }
+        location /fast {
+            limit_req    zone=fast  burst=1;
+        }
+    }
+}
+
+EOF
+
+$t->write_file('test1.html', 'XtestX');
+$t->write_file('long.html', "1234567890\n" x (1 << 16));
+$t->write_file('fast.html', 'XtestX');
+$t->run();
+
+###############################################################################
+
+like(http_get('/test1.html'), qr/^HTTP\/1.. 200 /m, 'request');
+http_get('/test1.html');
+like(http_get('/test1.html'), qr/^HTTP\/1.. 503 /m, 'request rejected');
+http_get('/test1.html');
+http_get('/test1.html');
+
+# Second request will be delayed by limit_req, make sure it isn't truncated.
+# The bug only manifests itself if buffer will be filled, so sleep for a while
+# before reading response.
+
+my $l1 = length(http_get('/long.html'));
+my $l2 = length(http_get('/long.html', sleep => 1.1));
+is($l2, $l1, 'delayed big request not truncated');
+
+# make sure rejected requests are not counted, and access is again allowed
+# after 1/rate seconds
+
+like(http_get('/test1.html'), qr/^HTTP\/1.. 200 /m, 'rejects not counted');
+
+# make sure negative excess values are handled properly
+
+http_get('/fast.html');
+select undef, undef, undef, 0.1;
+like(http_get('/fast.html'), qr/^HTTP\/1.. 200 /m, 'negative excess');
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mail_imap.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,122 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for nginx mail imap module.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+use IO::Socket;
+use MIME::Base64;
+use Socket qw/ CRLF /;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx;
+use Test::Nginx::IMAP;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+local $SIG{PIPE} = 'IGNORE';
+
+my $t = Test::Nginx->new()
+	->has(qw/mail imap http rewrite/)->plan(8)
+	->run_daemon(\&Test::Nginx::IMAP::imap_test_daemon)
+	->write_file_expand('nginx.conf', <<'EOF')->run();
+
+%%TEST_GLOBALS%%
+
+master_process off;
+daemon         off;
+
+events {
+}
+
+mail {
+    proxy_pass_error_message  on;
+    auth_http  http://127.0.0.1:8080/mail/auth;
+
+    server {
+        listen     127.0.0.1:8143;
+        protocol   imap;
+    }
+}
+
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  localhost;
+
+        location = /mail/auth {
+            set $reply ERROR;
+
+            if ($http_auth_smtp_to ~ example.com) {
+                set $reply OK;
+            }
+
+            set $userpass "$http_auth_user:$http_auth_pass";
+            if ($userpass ~ '^test@example.com:secret$') {
+                set $reply OK;
+            }
+
+            add_header Auth-Status $reply;
+            add_header Auth-Server 127.0.0.1;
+            add_header Auth-Port 8144;
+            add_header Auth-Wait 1;
+            return 204;
+        }
+    }
+}
+
+EOF
+
+###############################################################################
+
+my $s = Test::Nginx::IMAP->new();
+$s->ok('greeting');
+
+# auth plain
+
+$s->send('1 AUTHENTICATE PLAIN ' . encode_base64("\0test\@example.com\0bad", ''));
+$s->check(qr/^\S+ NO/, 'auth plain with bad password');
+
+$s->send('1 AUTHENTICATE PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
+$s->ok('auth plain');
+
+# auth login simple
+
+$s = Test::Nginx::IMAP->new();
+$s->read();
+
+$s->send('1 AUTHENTICATE LOGIN');
+$s->check(qr/\+ VXNlcm5hbWU6/, 'auth login username challenge');
+
+$s->send(encode_base64('test@example.com', ''));
+$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login password challenge');
+
+$s->send(encode_base64('secret', ''));
+$s->ok('auth login simple');
+
+# auth login with username
+
+$s = Test::Nginx::IMAP->new();
+$s->read();
+
+$s->send('1 AUTHENTICATE LOGIN ' . encode_base64('test@example.com', ''));
+$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login with username password challenge');
+
+$s->send(encode_base64('secret', ''));
+$s->ok('auth login with username');
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mail_pop3.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,122 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for nginx mail pop3 module.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+use IO::Socket;
+use MIME::Base64;
+use Socket qw/ CRLF /;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx;
+use Test::Nginx::POP3;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+local $SIG{PIPE} = 'IGNORE';
+
+my $t = Test::Nginx->new()
+	->has(qw/mail pop3 http rewrite/)->plan(8)
+	->run_daemon(\&Test::Nginx::POP3::pop3_test_daemon)
+	->write_file_expand('nginx.conf', <<'EOF')->run();
+
+%%TEST_GLOBALS%%
+
+master_process off;
+daemon         off;
+
+events {
+}
+
+mail {
+    proxy_pass_error_message  on;
+    auth_http  http://127.0.0.1:8080/mail/auth;
+
+    server {
+        listen     127.0.0.1:8110;
+        protocol   pop3;
+    }
+}
+
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  localhost;
+
+        location = /mail/auth {
+            set $reply ERROR;
+
+            if ($http_auth_smtp_to ~ example.com) {
+                set $reply OK;
+            }
+
+            set $userpass "$http_auth_user:$http_auth_pass";
+            if ($userpass ~ '^test@example.com:secret$') {
+                set $reply OK;
+            }
+
+            add_header Auth-Status $reply;
+            add_header Auth-Server 127.0.0.1;
+            add_header Auth-Port 8111;
+            add_header Auth-Wait 1;
+            return 204;
+        }
+    }
+}
+
+EOF
+
+###############################################################################
+
+my $s = Test::Nginx::POP3->new();
+$s->ok('greeting');
+
+# auth plain
+
+$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0bad", ''));
+$s->check(qr/^-ERR/, 'auth plain with bad password');
+
+$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
+$s->ok('auth plain');
+
+# auth login simple
+
+$s = Test::Nginx::POP3->new();
+$s->read();
+
+$s->send('AUTH LOGIN');
+$s->check(qr/\+ VXNlcm5hbWU6/, 'auth login username challenge');
+
+$s->send(encode_base64('test@example.com', ''));
+$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login password challenge');
+
+$s->send(encode_base64('secret', ''));
+$s->ok('auth login simple');
+
+# auth login with username
+
+$s = Test::Nginx::POP3->new();
+$s->read();
+
+$s->send('AUTH LOGIN ' . encode_base64('test@example.com', ''));
+$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login with username password challenge');
+
+$s->send(encode_base64('secret', ''));
+$s->ok('auth login with username');
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mail_smtp.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,236 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for nginx mail smtp module.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+use MIME::Base64;
+use Socket qw/ CRLF /;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx;
+use Test::Nginx::SMTP;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+local $SIG{PIPE} = 'IGNORE';
+
+my $t = Test::Nginx->new()
+	->has(qw/mail smtp http rewrite/)->plan(25)
+	->run_daemon(\&Test::Nginx::SMTP::smtp_test_daemon)
+	->write_file_expand('nginx.conf', <<'EOF')->run();
+
+%%TEST_GLOBALS%%
+
+master_process off;
+daemon         off;
+
+events {
+}
+
+mail {
+    proxy_pass_error_message  on;
+    auth_http  http://127.0.0.1:8080/mail/auth;
+    xclient    off;
+
+    server {
+        listen     127.0.0.1:8025;
+        protocol   smtp;
+        smtp_auth  login plain none;
+    }
+}
+
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  localhost;
+
+        location = /mail/auth {
+            set $reply ERROR;
+
+            if ($http_auth_smtp_to ~ example.com) {
+                set $reply OK;
+            }
+
+            set $userpass "$http_auth_user:$http_auth_pass";
+            if ($userpass ~ '^test@example.com:secret$') {
+                set $reply OK;
+            }
+
+            add_header Auth-Status $reply;
+            add_header Auth-Server 127.0.0.1;
+            add_header Auth-Port 8026;
+            add_header Auth-Wait 1;
+            return 204;
+        }
+    }
+}
+
+EOF
+
+###############################################################################
+
+my $s = Test::Nginx::SMTP->new();
+$s->check(qr/^220 /, "greeting");
+
+$s->send('EHLO example.com');
+$s->check(qr/^250 /, "ehlo");
+
+$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0bad", ''));
+$s->check(qr/^5.. /, 'auth plain with bad password');
+
+$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
+$s->authok('auth plain');
+
+# We are talking to backend from this point
+
+$s->send('MAIL FROM:<test@example.com> SIZE=100');
+$s->ok('mail from after auth');
+
+$s->send('RSET');
+$s->ok('rset');
+
+$s->send('MAIL FROM:<test@xn--e1afmkfd.xn--80akhbyknj4f> SIZE=100');
+$s->ok("idn mail from (example.test in russian)");
+
+$s->send('QUIT');
+$s->ok("quit");
+
+# Try auth login in simple form
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('EHLO example.com');
+$s->read();
+
+$s->send('AUTH LOGIN');
+$s->check(qr/^334 VXNlcm5hbWU6/, 'auth login simple username challenge');
+$s->send(encode_base64('test@example.com', ''));
+$s->check(qr/^334 UGFzc3dvcmQ6/, 'auth login simple password challenge');
+$s->send(encode_base64('secret', ''));
+$s->authok('auth login simple');
+
+# Try auth plain with username.  Details:
+#
+# [MS-XLOGIN]: SMTP Protocol AUTH LOGIN Extension Specification
+# http://download.microsoft.com/download/5/D/D/5DD33FDF-91F5-496D-9884-0A0B0EE698BB/%5BMS-XLOGIN%5D.pdf
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('EHLO example.com');
+$s->read();
+
+$s->send('AUTH LOGIN ' . encode_base64('test@example.com', ''));
+$s->check(qr/^334 UGFzc3dvcmQ6/, 'auth login with username password challenge');
+$s->send(encode_base64('secret', ''));
+$s->authok('auth login with username');
+
+# Try auth plain with pipelining
+
+TODO: {
+local $TODO = 'pipelining not in official nginx';
+local $SIG{__WARN__} = sub {};
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('EHLO example.com');
+$s->read();
+
+$s->send('INVALID COMMAND WITH ARGUMENTS' . CRLF
+	. 'RSET');
+$s->read();
+$s->ok('pipelined rset after invalid command');
+
+$s->send('AUTH PLAIN '
+	. encode_base64("\0test\@example.com\0bad", '') . CRLF
+	. 'MAIL FROM:<test@example.com> SIZE=100');
+$s->read();
+$s->ok('mail from after failed pipelined auth');
+
+$s->send('AUTH PLAIN '
+	. encode_base64("\0test\@example.com\0secret", '') . CRLF
+	. 'MAIL FROM:<test@example.com> SIZE=100');
+$s->read();
+$s->ok('mail from after pipelined auth');
+
+}
+
+# Try auth none
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('EHLO example.com');
+$s->read();
+
+$s->send('MAIL FROM:<test@example.com> SIZE=100');
+$s->ok('auth none - mail from');
+
+$s->send('RCPT TO:<test@example.com>');
+$s->ok('auth none - rcpt to');
+
+$s->send('RSET');
+$s->ok('auth none - rset, should go to backend');
+
+# Auth none with pipelining
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('EHLO example.com');
+$s->read();
+
+$s->send('MAIL FROM:<test@example.com> SIZE=100' . CRLF
+	. 'RCPT TO:<test@example.com>' . CRLF
+	. 'RSET');
+
+$s->ok('pipelined mail from');
+
+TODO: {
+local $TODO = 'pipelining not in official nginx';
+local $SIG{__WARN__} = sub {};
+
+$s->ok('pipelined rcpt to');
+$s->ok('pipelined rset');
+
+}
+
+# Connection must stay even if error returned to rcpt to command
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('EHLO example.com');
+$s->read();
+
+$s->send('MAIL FROM:<test@example.com> SIZE=100');
+$s->read(); # skip mail from reply
+
+$s->send('RCPT TO:<example.com>');
+$s->check(qr/^5.. /, "bad rcpt to");
+
+$s->send('RCPT TO:<test@example.com>');
+$s->ok('good rcpt to');
+
+# Make sure command splitted into many packets processed correctly
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+
+log_out('HEL');
+$s->print('HEL');
+$s->send('O example.com');
+$s->ok('splitted command');
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mail_smtp_greeting_delay.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx;
+use Test::Nginx::SMTP;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+my $t = Test::Nginx->new()->has(qw/mail smtp http/)->plan(2)
+	->write_file_expand('nginx.conf', <<'EOF')->run();
+
+%%TEST_GLOBALS%%
+
+master_process off;
+daemon         off;
+
+events {
+}
+
+mail {
+    proxy_pass_error_message  on;
+    auth_http  http://127.0.0.1:8080/mail/auth;
+    xclient    off;
+
+    server {
+        listen     127.0.0.1:8025;
+        protocol   smtp;
+        smtp_greeting_delay  100ms;
+    }
+}
+
+http {
+    # stub to avoid SIGSEGV when perl module compiled in, <= 0.7.30
+}
+
+EOF
+
+###############################################################################
+
+# With smtp_greeting_delay session expected to be closed after first error
+# message if client sent something before greeting.
+
+my $s = Test::Nginx::SMTP->new();
+$s->send('HELO example.com');
+$s->check(qr/^5.. /, "command before greeting - session must be rejected");
+
+TODO: {
+local $TODO = 'not in official nginx yet';
+
+ok($s->eof(), "session have to be closed");
+
+}
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mail_smtp_xclient.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,141 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+use MIME::Base64;
+use Socket qw/ CRLF /;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx;
+use Test::Nginx::SMTP;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+local $SIG{PIPE} = 'IGNORE';
+
+my $t = Test::Nginx->new()->has(qw/mail smtp http/)->plan(6)
+	->run_daemon(\&Test::Nginx::SMTP::smtp_test_daemon)
+	->write_file_expand('nginx.conf', <<'EOF')->run();
+
+%%TEST_GLOBALS%%
+
+master_process off;
+daemon         off;
+
+events {
+}
+
+mail {
+    proxy_pass_error_message  on;
+    auth_http  http://127.0.0.1:8080/mail/auth;
+    xclient    on;
+
+    server {
+        listen     127.0.0.1:8025;
+        protocol   smtp;
+        smtp_auth  login plain none;
+    }
+}
+
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  localhost;
+
+        location = /mail/auth {
+            add_header Auth-Status OK;
+            add_header Auth-Server 127.0.0.1;
+            add_header Auth-Port   8026;
+            add_header Auth-Wait   1;
+            return 204;
+        }
+    }
+}
+
+EOF
+
+###############################################################################
+
+# When XCLIENT's HELO= argument isn't used, the  following combinations may be
+# send to backend with xclient on:
+#
+# xclient
+# xclient, helo
+# xclient, ehlo
+# xclient, from, rcpt
+# xclient, helo, from, rcpt
+# xclient, ehlo, from, rcpt
+#
+# Test them in order.
+
+# xclient
+
+my $s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
+$s->authok('xclient');
+
+# xclient, helo
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('HELO example.com');
+$s->read();
+$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
+$s->authok('xclient, helo');
+
+# xclient, ehlo
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('EHLO example.com');
+$s->read();
+$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
+$s->authok('xclient, ehlo');
+
+# xclient, from, rcpt
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('MAIL FROM:<test@example.com>');
+$s->read();
+$s->send('RCPT TO:<test@example.com>');
+$s->ok('xclient, from');
+
+# xclient, helo, from, rcpt
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('HELO example.com');
+$s->read();
+$s->send('MAIL FROM:<test@example.com>');
+$s->read();
+$s->send('RCPT TO:<test@example.com>');
+$s->ok('xclient, helo, from');
+
+# xclient, ehlo, from, rcpt
+
+$s = Test::Nginx::SMTP->new();
+$s->read();
+$s->send('EHLO example.com');
+$s->read();
+$s->send('MAIL FROM:<test@example.com>');
+$s->read();
+$s->send('RCPT TO:<test@example.com>');
+$s->ok('xclient, ehlo, from');
+
+###############################################################################
--- a/memcached-fake.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Test for memcached backend with fake daemon.
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-use Socket qw/ CRLF /;
-
-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 memcached ssi/)->plan(3)
-	->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 / {
-            set $memcached_key $uri;
-            memcached_pass 127.0.0.1:8081;
-        }
-
-        location /ssi {
-            default_type text/html;
-            ssi on;
-        }
-    }
-}
-
-EOF
-
-$t->write_file('ssi.html', '<!--#include virtual="/" set="blah" -->blah: <!--#echo var="blah" -->');
-$t->run_daemon(\&memcached_fake_daemon);
-$t->run();
-
-###############################################################################
-
-like(http_get('/'), qr/SEE-THIS/, 'memcached split trailer');
-
-like(http_get('/ssi.html'), qr/SEE-THIS/, 'memcached ssi var');
-
-like(`grep -F '[error]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no error');
-
-###############################################################################
-
-sub memcached_fake_daemon {
-	my $server = IO::Socket::INET->new(
-		Proto => 'tcp',
-		LocalAddr => '127.0.0.1:8081',
-		Listen => 5,
-		Reuse => 1
-	)
-		or die "Can't create listening socket: $!\n";
-
-	while (my $client = $server->accept()) {
-		$client->autoflush(1);
-
-		while (<$client>) {
-			last if (/\x0d\x0a$/);
-		}
-
-		print $client 'VALUE / 0 8' . CRLF;
-		print $client 'SEE-TH';
-		select(undef, undef, undef, 0.1);
-		print $client 'IS';
-		select(undef, undef, undef, 0.1);
-		print $client CRLF . 'EN';
-		select(undef, undef, undef, 0.1);
-		print $client 'D' . CRLF;
-		close $client;
-	}
-}
-
-###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memcached_fake.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,99 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Test for memcached backend with fake daemon.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+use Socket qw/ CRLF /;
+
+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 memcached ssi/)->plan(3)
+	->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 / {
+            set $memcached_key $uri;
+            memcached_pass 127.0.0.1:8081;
+        }
+
+        location /ssi {
+            default_type text/html;
+            ssi on;
+        }
+    }
+}
+
+EOF
+
+$t->write_file('ssi.html', '<!--#include virtual="/" set="blah" -->blah: <!--#echo var="blah" -->');
+$t->run_daemon(\&memcached_fake_daemon);
+$t->run();
+
+###############################################################################
+
+like(http_get('/'), qr/SEE-THIS/, 'memcached split trailer');
+
+like(http_get('/ssi.html'), qr/SEE-THIS/, 'memcached ssi var');
+
+like(`grep -F '[error]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no error');
+
+###############################################################################
+
+sub memcached_fake_daemon {
+	my $server = IO::Socket::INET->new(
+		Proto => 'tcp',
+		LocalAddr => '127.0.0.1:8081',
+		Listen => 5,
+		Reuse => 1
+	)
+		or die "Can't create listening socket: $!\n";
+
+	while (my $client = $server->accept()) {
+		$client->autoflush(1);
+
+		while (<$client>) {
+			last if (/\x0d\x0a$/);
+		}
+
+		print $client 'VALUE / 0 8' . CRLF;
+		print $client 'SEE-TH';
+		select(undef, undef, undef, 0.1);
+		print $client 'IS';
+		select(undef, undef, undef, 0.1);
+		print $client CRLF . 'EN';
+		select(undef, undef, undef, 0.1);
+		print $client 'D' . CRLF;
+		close $client;
+	}
+}
+
+###############################################################################
--- a/not-modified.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for not modified filter 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('http')->plan(4)
-	->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 / {
-            if_modified_since before;
-        }
-    }
-}
-
-EOF
-
-$t->write_file('t', '');
-
-$t->run();
-
-###############################################################################
-
-like(http_get_ims('/t', 'Wed, 08 Jul 2037 22:53:52 GMT'), qr/304/,
-	'0x7F000000');
-like(http_get_ims('/t', 'Tue, 19 Jan 2038 03:14:07 GMT'), qr/304/,
-	'0x7FFFFFFF');
-
-SKIP: {
-	skip "only for 32-bit time_t", 2 if (gmtime(0xFFFFFFFF))[5] == 206;
-
-	like(http_get_ims('/t', 'Tue, 19 Jan 2038 03:14:08 GMT'), qr/200/,
-		'0x7FFFFFFF + 1');
-	like(http_get_ims('/t', 'Fri, 25 Feb 2174 09:42:23 GMT'), qr/200/,
-		'0x17FFFFFFF');
-}
-
-###############################################################################
-
-sub http_get_ims {
-        my ($url, $ims) = @_;
-        return http(<<EOF);
-GET $url HTTP/1.0
-Host: localhost
-If-Modified-Since: $ims
-
-EOF
-}
-
-###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/not_modified.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for not modified filter 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('http')->plan(4)
+	->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 / {
+            if_modified_since before;
+        }
+    }
+}
+
+EOF
+
+$t->write_file('t', '');
+
+$t->run();
+
+###############################################################################
+
+like(http_get_ims('/t', 'Wed, 08 Jul 2037 22:53:52 GMT'), qr/304/,
+	'0x7F000000');
+like(http_get_ims('/t', 'Tue, 19 Jan 2038 03:14:07 GMT'), qr/304/,
+	'0x7FFFFFFF');
+
+SKIP: {
+	skip "only for 32-bit time_t", 2 if (gmtime(0xFFFFFFFF))[5] == 206;
+
+	like(http_get_ims('/t', 'Tue, 19 Jan 2038 03:14:08 GMT'), qr/200/,
+		'0x7FFFFFFF + 1');
+	like(http_get_ims('/t', 'Fri, 25 Feb 2174 09:42:23 GMT'), qr/200/,
+		'0x17FFFFFFF');
+}
+
+###############################################################################
+
+sub http_get_ims {
+        my ($url, $ims) = @_;
+        return http(<<EOF);
+GET $url HTTP/1.0
+Host: localhost
+If-Modified-Since: $ims
+
+EOF
+}
+
+###############################################################################
--- a/perl-gzip.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for embedded perl module.
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-
-BEGIN { use FindBin; chdir($FindBin::Bin); }
-
-use lib 'lib';
-use Test::Nginx qw/ :DEFAULT :gzip /;
-
-###############################################################################
-
-select STDERR; $| = 1;
-select STDOUT; $| = 1;
-
-eval { require IO::Compress::Gzip; };
-Test::More::plan(skip_all => "IO::Compress::Gzip not found") if $@;
-
-my $t = Test::Nginx->new()->has(qw/http perl gzip/)->plan(2)
-	->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;
-
-        gzip on;
-        gzip_types text/plain;
-
-        location / {
-            perl 'sub {
-                my $r = shift;
-                $r->send_http_header("text/plain");
-                return OK if $r->header_only;
-                $r->print("TEST");
-                return OK;
-            }';
-        }
-
-        location /gz {
-            perl 'sub {
-                my $r = shift;
-                $r->header_out("Content-Encoding", "gzip");
-                $r->send_http_header("text/plain");
-                return OK if $r->header_only;
-                use IO::Compress::Gzip;
-                my $in = "TEST";
-                my $out;
-                IO::Compress::Gzip::gzip(\\$in => \\$out);
-                $r->print($out);
-                return OK;
-            }';
-        }
-    }
-}
-
-EOF
-
-$t->run();
-
-###############################################################################
-
-http_gzip_like(http_gzip_request('/'), qr/TEST/, 'perl response gzipped');
-
-TODO: {
-local $TODO = 'patch pending';
-
-http_gzip_like(http_gzip_request('/gz'), qr/TEST/, 'not doublegzipped');
-
-}
-
-###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/perl_gzip.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for embedded perl module.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx qw/ :DEFAULT :gzip /;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+eval { require IO::Compress::Gzip; };
+Test::More::plan(skip_all => "IO::Compress::Gzip not found") if $@;
+
+my $t = Test::Nginx->new()->has(qw/http perl gzip/)->plan(2)
+	->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;
+
+        gzip on;
+        gzip_types text/plain;
+
+        location / {
+            perl 'sub {
+                my $r = shift;
+                $r->send_http_header("text/plain");
+                return OK if $r->header_only;
+                $r->print("TEST");
+                return OK;
+            }';
+        }
+
+        location /gz {
+            perl 'sub {
+                my $r = shift;
+                $r->header_out("Content-Encoding", "gzip");
+                $r->send_http_header("text/plain");
+                return OK if $r->header_only;
+                use IO::Compress::Gzip;
+                my $in = "TEST";
+                my $out;
+                IO::Compress::Gzip::gzip(\\$in => \\$out);
+                $r->print($out);
+                return OK;
+            }';
+        }
+    }
+}
+
+EOF
+
+$t->run();
+
+###############################################################################
+
+http_gzip_like(http_gzip_request('/'), qr/TEST/, 'perl response gzipped');
+
+TODO: {
+local $TODO = 'patch pending';
+
+http_gzip_like(http_gzip_request('/gz'), qr/TEST/, 'not doublegzipped');
+
+}
+
+###############################################################################
--- a/pop3.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for nginx mail pop3 module.
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-
-use IO::Socket;
-use MIME::Base64;
-use Socket qw/ CRLF /;
-
-BEGIN { use FindBin; chdir($FindBin::Bin); }
-
-use lib 'lib';
-use Test::Nginx;
-use Test::Nginx::POP3;
-
-###############################################################################
-
-select STDERR; $| = 1;
-select STDOUT; $| = 1;
-
-local $SIG{PIPE} = 'IGNORE';
-
-my $t = Test::Nginx->new()
-	->has(qw/mail pop3 http rewrite/)->plan(8)
-	->run_daemon(\&Test::Nginx::POP3::pop3_test_daemon)
-	->write_file_expand('nginx.conf', <<'EOF')->run();
-
-%%TEST_GLOBALS%%
-
-master_process off;
-daemon         off;
-
-events {
-}
-
-mail {
-    proxy_pass_error_message  on;
-    auth_http  http://127.0.0.1:8080/mail/auth;
-
-    server {
-        listen     127.0.0.1:8110;
-        protocol   pop3;
-    }
-}
-
-http {
-    %%TEST_GLOBALS_HTTP%%
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  localhost;
-
-        location = /mail/auth {
-            set $reply ERROR;
-
-            if ($http_auth_smtp_to ~ example.com) {
-                set $reply OK;
-            }
-
-            set $userpass "$http_auth_user:$http_auth_pass";
-            if ($userpass ~ '^test@example.com:secret$') {
-                set $reply OK;
-            }
-
-            add_header Auth-Status $reply;
-            add_header Auth-Server 127.0.0.1;
-            add_header Auth-Port 8111;
-            add_header Auth-Wait 1;
-            return 204;
-        }
-    }
-}
-
-EOF
-
-###############################################################################
-
-my $s = Test::Nginx::POP3->new();
-$s->ok('greeting');
-
-# auth plain
-
-$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0bad", ''));
-$s->check(qr/^-ERR/, 'auth plain with bad password');
-
-$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
-$s->ok('auth plain');
-
-# auth login simple
-
-$s = Test::Nginx::POP3->new();
-$s->read();
-
-$s->send('AUTH LOGIN');
-$s->check(qr/\+ VXNlcm5hbWU6/, 'auth login username challenge');
-
-$s->send(encode_base64('test@example.com', ''));
-$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login password challenge');
-
-$s->send(encode_base64('secret', ''));
-$s->ok('auth login simple');
-
-# auth login with username
-
-$s = Test::Nginx::POP3->new();
-$s->read();
-
-$s->send('AUTH LOGIN ' . encode_base64('test@example.com', ''));
-$s->check(qr/\+ UGFzc3dvcmQ6/, 'auth login with username password challenge');
-
-$s->send(encode_base64('secret', ''));
-$s->ok('auth login with username');
-
-###############################################################################
--- a/proxy-cache.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for http proxy cache.
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-
-BEGIN { use FindBin; chdir($FindBin::Bin); }
-
-use lib 'lib';
-use Test::Nginx qw/ :DEFAULT :gzip /;
-
-###############################################################################
-
-select STDERR; $| = 1;
-select STDOUT; $| = 1;
-
-my $t = Test::Nginx->new()->has(qw/http proxy cache gzip/)->plan(12)
-	->write_file_expand('nginx.conf', <<'EOF');
-
-%%TEST_GLOBALS%%
-
-master_process off;
-daemon         off;
-
-events {
-}
-
-http {
-    %%TEST_GLOBALS_HTTP%%
-
-    proxy_cache_path   %%TESTDIR%%/cache  levels=1:2
-                       keys_zone=NAME:10m;
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  localhost;
-
-        gzip on;
-        gzip_min_length 0;
-
-        location / {
-            proxy_pass    http://127.0.0.1:8081;
-
-            proxy_cache   NAME;
-
-            proxy_cache_valid   200 302  1s;
-            proxy_cache_valid   301      1d;
-            proxy_cache_valid   any      1m;
-
-            proxy_cache_min_uses  1;
-
-            proxy_cache_use_stale  error timeout invalid_header http_500
-                                   http_404;
-        }
-
-        location /fake/ {
-            proxy_pass    http://127.0.0.1:8082;
-            proxy_cache   NAME;
-        }
-    }
-    server {
-        listen       127.0.0.1:8081;
-        server_name  localhost;
-
-        location / {
-        }
-    }
-}
-
-EOF
-
-$t->write_file('t.html', 'SEE-THIS');
-$t->write_file('t2.html', 'SEE-THIS');
-$t->write_file('empty.html', '');
-$t->run_daemon(\&http_fake_daemon);
-$t->run();
-
-###############################################################################
-
-like(http_get('/t.html'), qr/SEE-THIS/, 'proxy request');
-
-$t->write_file('t.html', 'NOOP');
-like(http_get('/t.html'), qr/SEE-THIS/, 'proxy request cached');
-
-unlike(http_head('/t2.html'), qr/SEE-THIS/, 'head request');
-like(http_get('/t2.html'), qr/SEE-THIS/, 'get after head');
-unlike(http_head('/t2.html'), qr/SEE-THIS/, 'head after get');
-
-like(http_get_range('/t.html', 'Range: bytes=4-'), qr/^THIS/m, 'cached range');
-like(http_get_range('/t.html', 'Range: bytes=0-2,4-'), qr/^SEE.*^THIS/ms,
-	'cached multipart range');
-
-like(http_get('/empty.html'), qr/HTTP/, 'empty get first');
-like(http_get('/empty.html'), qr/HTTP/, 'empty get second');
-
-{
-local $TODO = 'not fixed yet';
-
-sleep(2);
-unlink $t->testdir() . '/t.html';
-like(http_gzip_request('/t.html'),
-	qr/HTTP.*1c\x0d\x0a.{28}\x0d\x0a0\x0d\x0a\x0d\x0a\z/s,
-	'non-empty get stale');
-}
-
-{
-local $TODO = 'broken in 0.8.31';
-
-unlink $t->testdir() . '/empty.html';
-like(http_gzip_request('/empty.html'),
-	qr/HTTP.*14\x0d\x0a.{20}\x0d\x0a0\x0d\x0a\x0d\x0a\z/s,
-	'empty get stale');
-}
-
-{
-local $TODO = 'patch pending';
-
-http_get('/fake/unfinished');
-like(http_get('/fake/unfinished'), qr/unfinished 2/, 'unfinished not cached');
-}
-
-###############################################################################
-
-sub http_get_range {
-        my ($url, $extra) = @_;
-        return http(<<EOF);
-GET $url HTTP/1.1
-Host: localhost
-Connection: close
-$extra
-
-EOF
-}
-
-###############################################################################
-
-sub http_fake_daemon {
-	my $server = IO::Socket::INET->new(
-		Proto => 'tcp',
-		LocalAddr => '127.0.0.1:8082',
-		Listen => 5,
-		Reuse => 1
-	)
-		or die "Can't create listening socket: $!\n";
-
-	my $num = 0;
-
-	while (my $client = $server->accept()) {
-		$client->autoflush(1);
-
-		while (<$client>) {
-			last if (/^\x0d?\x0a?$/);
-		}
-
-		$num++;
-		print $client <<"EOF";
-HTTP/1.1 200 OK
-Content-Length: 100
-Cache-Control: max-age=300
-Connection: close
-
-unfinished $num
-EOF
-	}
-}
-
-###############################################################################
--- a/proxy-chunked.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Test for http backend returning response with Transfer-Encoding: chunked.
-
-# Since nginx uses HTTP/1.0 in requests to backend it's backend bug, but we
-# want to handle this gracefully.  And anyway chunked support will be required
-# for HTTP/1.1 backend connections.
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-
-use IO::Select;
-
-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 ssi/)->plan(3);
-
-$t->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 / {
-            proxy_pass http://127.0.0.1:8081;
-            proxy_read_timeout 1s;
-        }
-        location /nobuffering {
-            proxy_pass http://127.0.0.1:8081;
-            proxy_read_timeout 1s;
-            proxy_buffering off;
-        }
-        location /inmemory.html {
-            ssi on;
-        }
-    }
-}
-
-EOF
-
-$t->write_file('inmemory.html',
-	'<!--#include virtual="/" set="one" --><!--#echo var="one" -->');
-
-$t->run_daemon(\&http_chunked_daemon);
-$t->run();
-
-###############################################################################
-
-{
-local $TODO = 'not yet';
-
-like(http_get('/'), qr/\x0d\x0aSEE-THIS$/s, 'chunked');
-like(http_get('/nobuffering'), qr/\x0d\x0aSEE-THIS$/s, 'chunked nobuffering');
-like(http_get('/inmemory.html'), qr/\x0d\x0aSEE-THIS$/s, 'chunked inmemory');
-}
-
-###############################################################################
-
-sub http_chunked_daemon {
-	my $server = IO::Socket::INET->new(
-		Proto => 'tcp',
-		LocalAddr => '127.0.0.1:8081',
-		Listen => 5,
-		Reuse => 1
-	)
-		or die "Can't create listening socket: $!\n";
-
-	while (my $client = $server->accept()) {
-		$client->autoflush(1);
-
-		while (<$client>) {
-			last if (/^\x0d?\x0a?$/);
-		}
-
-		print $client <<'EOF';
-HTTP/1.1 200 OK
-Connection: close
-Transfer-Encoding: chunked
-
-9
-SEE-THIS
-
-0
-
-EOF
-
-		close $client;
-	}
-}
-
-###############################################################################
--- a/proxy-noclose.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Test for http backend not closing connection properly after sending full
-# reply.  This is in fact backend bug, but it seems common, and anyway
-# correct handling is required to support persistent connections.
-
-# There are actually 2 nginx problems here:
-#
-# 1. It doesn't send reply in-time even if got Content-Length and all the data.
-#
-# 2. If upstream times out some data may be left in input buffer and won't be
-#    sent to downstream.
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-
-use IO::Select;
-
-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/)->plan(4);
-
-$t->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 / {
-            proxy_pass http://127.0.0.1:8081;
-            proxy_read_timeout 1s;
-        }
-
-        location /uselen {
-            proxy_pass http://127.0.0.1:8081;
-
-            # test will wait only 2s for reply, we it will fail if
-            # Content-Length not used as a hint
-
-            proxy_read_timeout 10s;
-        }
-    }
-}
-
-EOF
-
-$t->run_daemon(\&http_noclose_daemon);
-$t->run();
-
-###############################################################################
-
-TODO: {
-local $TODO = 'not fixed yet, patches under review';
-local $SIG{__WARN__} = sub {};
-
-like(http_get('/'), qr/SEE-THIS/, 'request to bad backend');
-like(http_get('/multi'), qr/AND-THIS/, 'bad backend - multiple packets');
-like(http_get('/nolen'), qr/SEE-THIS/, 'bad backend - no content length');
-like(http_get('/uselen'), qr/SEE-THIS/, 'content-length actually used');
-
-}
-
-###############################################################################
-
-sub http_noclose_daemon {
-	my $server = IO::Socket::INET->new(
-		Proto => 'tcp',
-		LocalAddr => '127.0.0.1:8081',
-		Listen => 5,
-		Reuse => 1
-	)
-		or die "Can't create listening socket: $!\n";
-
-	while (my $client = $server->accept()) {
-		$client->autoflush(1);
-
-		my $multi = 0;
-		my $nolen = 0;
-
-		while (<$client>) {
-			$multi = 1 if /multi/;
-			$nolen = 1 if /nolen/;
-			last if (/^\x0d?\x0a?$/);
-		}
-
-		if ($nolen) {
-
-			print $client <<'EOF';
-HTTP/1.1 200 OK
-Connection: close
-
-TEST-OK-IF-YOU-SEE-THIS
-EOF
-		} elsif ($multi) {
-
-			print $client <<"EOF";
-HTTP/1.1 200 OK
-Content-Length: 32
-Connection: close
-
-TEST-OK-IF-YOU-SEE-THIS
-EOF
-
-			select undef, undef, undef, 0.1;
-			print $client 'AND-THIS';
-
-		} else {
-
-			print $client <<"EOF";
-HTTP/1.1 200 OK
-Content-Length: 24
-Connection: close
-
-TEST-OK-IF-YOU-SEE-THIS
-EOF
-		}
-
-		my $select = IO::Select->new($client);
-		$select->can_read(10);
-		close $client;
-	}
-}
-
-###############################################################################
--- a/proxy-store.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for proxy_store 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();
-
-$t->write_file_expand('nginx.conf', <<'EOF')->has(qw/http proxy ssi/)->plan(7);
-
-%%TEST_GLOBALS%%
-
-master_process off;
-daemon         off;
-
-events {
-}
-
-http {
-    %%TEST_GLOBALS_HTTP%%
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  localhost;
-
-        location /store- {
-            proxy_pass http://127.0.0.1:8080/;
-            proxy_store on;
-        }
-        location /ssi.html {
-            ssi on;
-        }
-        location /index-nostore.html {
-            add_header  X-Accel-Expires  0;
-        }
-        location /index-big.html {
-            limit_rate  200k;
-        }
-    }
-}
-
-EOF
-
-$t->write_file('index.html', 'SEE-THIS');
-$t->write_file('index-nostore.html', 'SEE-THIS');
-$t->write_file('index-big.html', 'x' x (100 << 10));
-$t->write_file('ssi.html',
-	'<!--#include virtual="/store-index-big.html?1" -->' .
-	'<!--#include virtual="/store-index-big.html?2" -->'
-);
-$t->run();
-
-###############################################################################
-
-like(http_get('/store-index.html'), qr/SEE-THIS/, 'proxy request');
-ok(-e $t->testdir() . '/store-index.html', 'result stored');
-
-like(http_get('/store-index-nostore.html'), qr/SEE-THIS/,
-	'proxy request with x-accel-expires');
-
-TODO: {
-local $TODO = 'patch under review';
-
-ok(!-e $t->testdir() . '/store-index-nostore.html', 'result not stored');
-}
-
-ok(scalar @{[ glob $t->testdir() . '/proxy_temp/*' ]} == 0, 'no temp files');
-
-http_get('/store-index-big.html', aborted => 1, sleep => 0.1);
-sleep(1);
-
-ok(scalar @{[ glob $t->testdir() . '/proxy_temp/*' ]} == 0,
-	'no temp files after aborted request');
-
-TODO: {
-local $TODO = 'not fixed yet';
-
-http_get('/ssi.html', aborted => 1, sleep => 0.1);
-sleep(1);
-
-ok(scalar @{[ glob $t->testdir() . '/proxy_temp/*' ]} == 0,
-	'no temp files after aborted ssi');
-
-}
-
-###############################################################################
--- a/proxy-xar.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-#!/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(8);
-
-$t->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 /proxy {
-            proxy_pass http://127.0.0.1:8080/return-xar;
-        }
-        location /return-xar {
-            add_header  X-Accel-Redirect     /index.html;
-
-            # 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;
-        }
-    }
-}
-
-EOF
-
-$t->write_file('index.html', 'SEE-THIS');
-$t->run();
-
-###############################################################################
-
-my $r = http_get('/proxy');
-like($r, qr/SEE-THIS/, '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');
-
-###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/proxy_cache.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,174 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for http proxy cache.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx qw/ :DEFAULT :gzip /;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+my $t = Test::Nginx->new()->has(qw/http proxy cache gzip/)->plan(12)
+	->write_file_expand('nginx.conf', <<'EOF');
+
+%%TEST_GLOBALS%%
+
+master_process off;
+daemon         off;
+
+events {
+}
+
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    proxy_cache_path   %%TESTDIR%%/cache  levels=1:2
+                       keys_zone=NAME:10m;
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  localhost;
+
+        gzip on;
+        gzip_min_length 0;
+
+        location / {
+            proxy_pass    http://127.0.0.1:8081;
+
+            proxy_cache   NAME;
+
+            proxy_cache_valid   200 302  1s;
+            proxy_cache_valid   301      1d;
+            proxy_cache_valid   any      1m;
+
+            proxy_cache_min_uses  1;
+
+            proxy_cache_use_stale  error timeout invalid_header http_500
+                                   http_404;
+        }
+
+        location /fake/ {
+            proxy_pass    http://127.0.0.1:8082;
+            proxy_cache   NAME;
+        }
+    }
+    server {
+        listen       127.0.0.1:8081;
+        server_name  localhost;
+
+        location / {
+        }
+    }
+}
+
+EOF
+
+$t->write_file('t.html', 'SEE-THIS');
+$t->write_file('t2.html', 'SEE-THIS');
+$t->write_file('empty.html', '');
+$t->run_daemon(\&http_fake_daemon);
+$t->run();
+
+###############################################################################
+
+like(http_get('/t.html'), qr/SEE-THIS/, 'proxy request');
+
+$t->write_file('t.html', 'NOOP');
+like(http_get('/t.html'), qr/SEE-THIS/, 'proxy request cached');
+
+unlike(http_head('/t2.html'), qr/SEE-THIS/, 'head request');
+like(http_get('/t2.html'), qr/SEE-THIS/, 'get after head');
+unlike(http_head('/t2.html'), qr/SEE-THIS/, 'head after get');
+
+like(http_get_range('/t.html', 'Range: bytes=4-'), qr/^THIS/m, 'cached range');
+like(http_get_range('/t.html', 'Range: bytes=0-2,4-'), qr/^SEE.*^THIS/ms,
+	'cached multipart range');
+
+like(http_get('/empty.html'), qr/HTTP/, 'empty get first');
+like(http_get('/empty.html'), qr/HTTP/, 'empty get second');
+
+{
+local $TODO = 'not fixed yet';
+
+sleep(2);
+unlink $t->testdir() . '/t.html';
+like(http_gzip_request('/t.html'),
+	qr/HTTP.*1c\x0d\x0a.{28}\x0d\x0a0\x0d\x0a\x0d\x0a\z/s,
+	'non-empty get stale');
+}
+
+{
+local $TODO = 'broken in 0.8.31';
+
+unlink $t->testdir() . '/empty.html';
+like(http_gzip_request('/empty.html'),
+	qr/HTTP.*14\x0d\x0a.{20}\x0d\x0a0\x0d\x0a\x0d\x0a\z/s,
+	'empty get stale');
+}
+
+{
+local $TODO = 'patch pending';
+
+http_get('/fake/unfinished');
+like(http_get('/fake/unfinished'), qr/unfinished 2/, 'unfinished not cached');
+}
+
+###############################################################################
+
+sub http_get_range {
+        my ($url, $extra) = @_;
+        return http(<<EOF);
+GET $url HTTP/1.1
+Host: localhost
+Connection: close
+$extra
+
+EOF
+}
+
+###############################################################################
+
+sub http_fake_daemon {
+	my $server = IO::Socket::INET->new(
+		Proto => 'tcp',
+		LocalAddr => '127.0.0.1:8082',
+		Listen => 5,
+		Reuse => 1
+	)
+		or die "Can't create listening socket: $!\n";
+
+	my $num = 0;
+
+	while (my $client = $server->accept()) {
+		$client->autoflush(1);
+
+		while (<$client>) {
+			last if (/^\x0d?\x0a?$/);
+		}
+
+		$num++;
+		print $client <<"EOF";
+HTTP/1.1 200 OK
+Content-Length: 100
+Cache-Control: max-age=300
+Connection: close
+
+unfinished $num
+EOF
+	}
+}
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/proxy_chunked.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,116 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Test for http backend returning response with Transfer-Encoding: chunked.
+
+# Since nginx uses HTTP/1.0 in requests to backend it's backend bug, but we
+# want to handle this gracefully.  And anyway chunked support will be required
+# for HTTP/1.1 backend connections.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+use IO::Select;
+
+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 ssi/)->plan(3);
+
+$t->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 / {
+            proxy_pass http://127.0.0.1:8081;
+            proxy_read_timeout 1s;
+        }
+        location /nobuffering {
+            proxy_pass http://127.0.0.1:8081;
+            proxy_read_timeout 1s;
+            proxy_buffering off;
+        }
+        location /inmemory.html {
+            ssi on;
+        }
+    }
+}
+
+EOF
+
+$t->write_file('inmemory.html',
+	'<!--#include virtual="/" set="one" --><!--#echo var="one" -->');
+
+$t->run_daemon(\&http_chunked_daemon);
+$t->run();
+
+###############################################################################
+
+{
+local $TODO = 'not yet';
+
+like(http_get('/'), qr/\x0d\x0aSEE-THIS$/s, 'chunked');
+like(http_get('/nobuffering'), qr/\x0d\x0aSEE-THIS$/s, 'chunked nobuffering');
+like(http_get('/inmemory.html'), qr/\x0d\x0aSEE-THIS$/s, 'chunked inmemory');
+}
+
+###############################################################################
+
+sub http_chunked_daemon {
+	my $server = IO::Socket::INET->new(
+		Proto => 'tcp',
+		LocalAddr => '127.0.0.1:8081',
+		Listen => 5,
+		Reuse => 1
+	)
+		or die "Can't create listening socket: $!\n";
+
+	while (my $client = $server->accept()) {
+		$client->autoflush(1);
+
+		while (<$client>) {
+			last if (/^\x0d?\x0a?$/);
+		}
+
+		print $client <<'EOF';
+HTTP/1.1 200 OK
+Connection: close
+Transfer-Encoding: chunked
+
+9
+SEE-THIS
+
+0
+
+EOF
+
+		close $client;
+	}
+}
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/proxy_noclose.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,149 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Test for http backend not closing connection properly after sending full
+# reply.  This is in fact backend bug, but it seems common, and anyway
+# correct handling is required to support persistent connections.
+
+# There are actually 2 nginx problems here:
+#
+# 1. It doesn't send reply in-time even if got Content-Length and all the data.
+#
+# 2. If upstream times out some data may be left in input buffer and won't be
+#    sent to downstream.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+use IO::Select;
+
+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/)->plan(4);
+
+$t->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 / {
+            proxy_pass http://127.0.0.1:8081;
+            proxy_read_timeout 1s;
+        }
+
+        location /uselen {
+            proxy_pass http://127.0.0.1:8081;
+
+            # test will wait only 2s for reply, we it will fail if
+            # Content-Length not used as a hint
+
+            proxy_read_timeout 10s;
+        }
+    }
+}
+
+EOF
+
+$t->run_daemon(\&http_noclose_daemon);
+$t->run();
+
+###############################################################################
+
+TODO: {
+local $TODO = 'not fixed yet, patches under review';
+local $SIG{__WARN__} = sub {};
+
+like(http_get('/'), qr/SEE-THIS/, 'request to bad backend');
+like(http_get('/multi'), qr/AND-THIS/, 'bad backend - multiple packets');
+like(http_get('/nolen'), qr/SEE-THIS/, 'bad backend - no content length');
+like(http_get('/uselen'), qr/SEE-THIS/, 'content-length actually used');
+
+}
+
+###############################################################################
+
+sub http_noclose_daemon {
+	my $server = IO::Socket::INET->new(
+		Proto => 'tcp',
+		LocalAddr => '127.0.0.1:8081',
+		Listen => 5,
+		Reuse => 1
+	)
+		or die "Can't create listening socket: $!\n";
+
+	while (my $client = $server->accept()) {
+		$client->autoflush(1);
+
+		my $multi = 0;
+		my $nolen = 0;
+
+		while (<$client>) {
+			$multi = 1 if /multi/;
+			$nolen = 1 if /nolen/;
+			last if (/^\x0d?\x0a?$/);
+		}
+
+		if ($nolen) {
+
+			print $client <<'EOF';
+HTTP/1.1 200 OK
+Connection: close
+
+TEST-OK-IF-YOU-SEE-THIS
+EOF
+		} elsif ($multi) {
+
+			print $client <<"EOF";
+HTTP/1.1 200 OK
+Content-Length: 32
+Connection: close
+
+TEST-OK-IF-YOU-SEE-THIS
+EOF
+
+			select undef, undef, undef, 0.1;
+			print $client 'AND-THIS';
+
+		} else {
+
+			print $client <<"EOF";
+HTTP/1.1 200 OK
+Content-Length: 24
+Connection: close
+
+TEST-OK-IF-YOU-SEE-THIS
+EOF
+		}
+
+		my $select = IO::Select->new($client);
+		$select->can_read(10);
+		close $client;
+	}
+}
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/proxy_store.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,103 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for proxy_store 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();
+
+$t->write_file_expand('nginx.conf', <<'EOF')->has(qw/http proxy ssi/)->plan(7);
+
+%%TEST_GLOBALS%%
+
+master_process off;
+daemon         off;
+
+events {
+}
+
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  localhost;
+
+        location /store- {
+            proxy_pass http://127.0.0.1:8080/;
+            proxy_store on;
+        }
+        location /ssi.html {
+            ssi on;
+        }
+        location /index-nostore.html {
+            add_header  X-Accel-Expires  0;
+        }
+        location /index-big.html {
+            limit_rate  200k;
+        }
+    }
+}
+
+EOF
+
+$t->write_file('index.html', 'SEE-THIS');
+$t->write_file('index-nostore.html', 'SEE-THIS');
+$t->write_file('index-big.html', 'x' x (100 << 10));
+$t->write_file('ssi.html',
+	'<!--#include virtual="/store-index-big.html?1" -->' .
+	'<!--#include virtual="/store-index-big.html?2" -->'
+);
+$t->run();
+
+###############################################################################
+
+like(http_get('/store-index.html'), qr/SEE-THIS/, 'proxy request');
+ok(-e $t->testdir() . '/store-index.html', 'result stored');
+
+like(http_get('/store-index-nostore.html'), qr/SEE-THIS/,
+	'proxy request with x-accel-expires');
+
+TODO: {
+local $TODO = 'patch under review';
+
+ok(!-e $t->testdir() . '/store-index-nostore.html', 'result not stored');
+}
+
+ok(scalar @{[ glob $t->testdir() . '/proxy_temp/*' ]} == 0, 'no temp files');
+
+http_get('/store-index-big.html', aborted => 1, sleep => 0.1);
+sleep(1);
+
+ok(scalar @{[ glob $t->testdir() . '/proxy_temp/*' ]} == 0,
+	'no temp files after aborted request');
+
+TODO: {
+local $TODO = 'not fixed yet';
+
+http_get('/ssi.html', aborted => 1, sleep => 0.1);
+sleep(1);
+
+ok(scalar @{[ glob $t->testdir() . '/proxy_temp/*' ]} == 0,
+	'no temp files after aborted ssi');
+
+}
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/proxy_xar.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,84 @@
+#!/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(8);
+
+$t->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 /proxy {
+            proxy_pass http://127.0.0.1:8080/return-xar;
+        }
+        location /return-xar {
+            add_header  X-Accel-Redirect     /index.html;
+
+            # 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;
+        }
+    }
+}
+
+EOF
+
+$t->write_file('index.html', 'SEE-THIS');
+$t->run();
+
+###############################################################################
+
+my $r = http_get('/proxy');
+like($r, qr/SEE-THIS/, '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');
+
+###############################################################################
--- a/random-index.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for random index 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 random_index/)->plan(1)
-	->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 / {
-            random_index on;
-        }
-    }
-}
-
-EOF
-
-my $d = $t->testdir();
-
-mkdir("$d/x");
-mkdir("$d/x/test-dir");
-symlink("$d/x/test-dir", "$d/x/test-dir-link");
-
-$t->write_file('test-file', 'RIGHT');
-symlink("$d/test-file", "$d/x/test-file-link");
-
-$t->run();
-
-###############################################################################
-
-like(http_get('/x/'), qr/RIGHT/s, 'file');
-
-###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/random_index.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for random index 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 random_index/)->plan(1)
+	->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 / {
+            random_index on;
+        }
+    }
+}
+
+EOF
+
+my $d = $t->testdir();
+
+mkdir("$d/x");
+mkdir("$d/x/test-dir");
+symlink("$d/x/test-dir", "$d/x/test-dir-link");
+
+$t->write_file('test-file', 'RIGHT');
+symlink("$d/test-file", "$d/x/test-file-link");
+
+$t->run();
+
+###############################################################################
+
+like(http_get('/x/'), qr/RIGHT/s, 'file');
+
+###############################################################################
--- a/range-flv.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for range filter 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 flv/)->plan(12);
-
-$t->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 / {
-            flv;
-        }
-    }
-}
-
-EOF
-
-$t->write_file('t1.flv',
-	join('', map { sprintf "X%03dXXXXXX", $_ } (0 .. 99)));
-$t->run();
-
-###############################################################################
-
-my $t1;
-
-# FLV has 13 byte header at start.
-
-$t1 = http_get_range('/t1.flv?start=100', 'Range: bytes=0-9');
-like($t1, qr/206/, 'first bytes - 206 partial reply');
-like($t1, qr/Content-Length: 10/, 'first bytes - correct length');
-like($t1, qr/Content-Range: bytes 0-9\/913/, 'first bytes - content range');
-like($t1, qr/^FLV.{7}$/m, 'first bytes - correct content');
-
-$t1 = http_get_range('/t1.flv?start=100', 'Range: bytes=-10');
-like($t1, qr/206/, 'final bytes - 206 partial reply');
-like($t1, qr/Content-Length: 10/, 'final bytes - content length');
-like($t1, qr/Content-Range: bytes 903-912\/913/,
-	'final bytes - content range');
-like($t1, qr/^X099XXXXXX$/m, 'final bytes - correct content');
-
-$t1 = http_get_range('/t1.flv?start=100', 'Range: bytes=0-99');
-like($t1, qr/206/, 'multi buffers - 206 partial reply');
-like($t1, qr/Content-Length: 100/, 'multi buffers - content length');
-like($t1, qr/Content-Range: bytes 0-99\/913/, 'multi buffers - content range');
-like($t1, qr/^FLV.{10}X010XXXXXX(X01[1-7]XXXXXX){7}X018XXX$/m,
-	'multi buffers - correct content');
-
-###############################################################################
-
-sub http_get_range {
-	my ($url, $extra) = @_;
-	return http(<<EOF);
-GET $url HTTP/1.1
-Host: localhost
-Connection: close
-$extra
-
-EOF
-}
-
-###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/range_flv.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,93 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for range filter 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 flv/)->plan(12);
+
+$t->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 / {
+            flv;
+        }
+    }
+}
+
+EOF
+
+$t->write_file('t1.flv',
+	join('', map { sprintf "X%03dXXXXXX", $_ } (0 .. 99)));
+$t->run();
+
+###############################################################################
+
+my $t1;
+
+# FLV has 13 byte header at start.
+
+$t1 = http_get_range('/t1.flv?start=100', 'Range: bytes=0-9');
+like($t1, qr/206/, 'first bytes - 206 partial reply');
+like($t1, qr/Content-Length: 10/, 'first bytes - correct length');
+like($t1, qr/Content-Range: bytes 0-9\/913/, 'first bytes - content range');
+like($t1, qr/^FLV.{7}$/m, 'first bytes - correct content');
+
+$t1 = http_get_range('/t1.flv?start=100', 'Range: bytes=-10');
+like($t1, qr/206/, 'final bytes - 206 partial reply');
+like($t1, qr/Content-Length: 10/, 'final bytes - content length');
+like($t1, qr/Content-Range: bytes 903-912\/913/,
+	'final bytes - content range');
+like($t1, qr/^X099XXXXXX$/m, 'final bytes - correct content');
+
+$t1 = http_get_range('/t1.flv?start=100', 'Range: bytes=0-99');
+like($t1, qr/206/, 'multi buffers - 206 partial reply');
+like($t1, qr/Content-Length: 100/, 'multi buffers - content length');
+like($t1, qr/Content-Range: bytes 0-99\/913/, 'multi buffers - content range');
+like($t1, qr/^FLV.{10}X010XXXXXX(X01[1-7]XXXXXX){7}X018XXX$/m,
+	'multi buffers - correct content');
+
+###############################################################################
+
+sub http_get_range {
+	my ($url, $extra) = @_;
+	return http(<<EOF);
+GET $url HTTP/1.1
+Host: localhost
+Connection: close
+$extra
+
+EOF
+}
+
+###############################################################################
--- a/smtp-greeting-delay.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-
-BEGIN { use FindBin; chdir($FindBin::Bin); }
-
-use lib 'lib';
-use Test::Nginx;
-use Test::Nginx::SMTP;
-
-###############################################################################
-
-select STDERR; $| = 1;
-select STDOUT; $| = 1;
-
-my $t = Test::Nginx->new()->has(qw/mail smtp http/)->plan(2)
-	->write_file_expand('nginx.conf', <<'EOF')->run();
-
-%%TEST_GLOBALS%%
-
-master_process off;
-daemon         off;
-
-events {
-}
-
-mail {
-    proxy_pass_error_message  on;
-    auth_http  http://127.0.0.1:8080/mail/auth;
-    xclient    off;
-
-    server {
-        listen     127.0.0.1:8025;
-        protocol   smtp;
-        smtp_greeting_delay  100ms;
-    }
-}
-
-http {
-    # stub to avoid SIGSEGV when perl module compiled in, <= 0.7.30
-}
-
-EOF
-
-###############################################################################
-
-# With smtp_greeting_delay session expected to be closed after first error
-# message if client sent something before greeting.
-
-my $s = Test::Nginx::SMTP->new();
-$s->send('HELO example.com');
-$s->check(qr/^5.. /, "command before greeting - session must be rejected");
-
-TODO: {
-local $TODO = 'not in official nginx yet';
-
-ok($s->eof(), "session have to be closed");
-
-}
-
-###############################################################################
--- a/smtp-xclient.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-
-use MIME::Base64;
-use Socket qw/ CRLF /;
-
-BEGIN { use FindBin; chdir($FindBin::Bin); }
-
-use lib 'lib';
-use Test::Nginx;
-use Test::Nginx::SMTP;
-
-###############################################################################
-
-select STDERR; $| = 1;
-select STDOUT; $| = 1;
-
-local $SIG{PIPE} = 'IGNORE';
-
-my $t = Test::Nginx->new()->has(qw/mail smtp http/)->plan(6)
-	->run_daemon(\&Test::Nginx::SMTP::smtp_test_daemon)
-	->write_file_expand('nginx.conf', <<'EOF')->run();
-
-%%TEST_GLOBALS%%
-
-master_process off;
-daemon         off;
-
-events {
-}
-
-mail {
-    proxy_pass_error_message  on;
-    auth_http  http://127.0.0.1:8080/mail/auth;
-    xclient    on;
-
-    server {
-        listen     127.0.0.1:8025;
-        protocol   smtp;
-        smtp_auth  login plain none;
-    }
-}
-
-http {
-    %%TEST_GLOBALS_HTTP%%
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  localhost;
-
-        location = /mail/auth {
-            add_header Auth-Status OK;
-            add_header Auth-Server 127.0.0.1;
-            add_header Auth-Port   8026;
-            add_header Auth-Wait   1;
-            return 204;
-        }
-    }
-}
-
-EOF
-
-###############################################################################
-
-# When XCLIENT's HELO= argument isn't used, the  following combinations may be
-# send to backend with xclient on:
-#
-# xclient
-# xclient, helo
-# xclient, ehlo
-# xclient, from, rcpt
-# xclient, helo, from, rcpt
-# xclient, ehlo, from, rcpt
-#
-# Test them in order.
-
-# xclient
-
-my $s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
-$s->authok('xclient');
-
-# xclient, helo
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('HELO example.com');
-$s->read();
-$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
-$s->authok('xclient, helo');
-
-# xclient, ehlo
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('EHLO example.com');
-$s->read();
-$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
-$s->authok('xclient, ehlo');
-
-# xclient, from, rcpt
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('MAIL FROM:<test@example.com>');
-$s->read();
-$s->send('RCPT TO:<test@example.com>');
-$s->ok('xclient, from');
-
-# xclient, helo, from, rcpt
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('HELO example.com');
-$s->read();
-$s->send('MAIL FROM:<test@example.com>');
-$s->read();
-$s->send('RCPT TO:<test@example.com>');
-$s->ok('xclient, helo, from');
-
-# xclient, ehlo, from, rcpt
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('EHLO example.com');
-$s->read();
-$s->send('MAIL FROM:<test@example.com>');
-$s->read();
-$s->send('RCPT TO:<test@example.com>');
-$s->ok('xclient, ehlo, from');
-
-###############################################################################
--- a/smtp.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for nginx mail smtp module.
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-
-use MIME::Base64;
-use Socket qw/ CRLF /;
-
-BEGIN { use FindBin; chdir($FindBin::Bin); }
-
-use lib 'lib';
-use Test::Nginx;
-use Test::Nginx::SMTP;
-
-###############################################################################
-
-select STDERR; $| = 1;
-select STDOUT; $| = 1;
-
-local $SIG{PIPE} = 'IGNORE';
-
-my $t = Test::Nginx->new()
-	->has(qw/mail smtp http rewrite/)->plan(25)
-	->run_daemon(\&Test::Nginx::SMTP::smtp_test_daemon)
-	->write_file_expand('nginx.conf', <<'EOF')->run();
-
-%%TEST_GLOBALS%%
-
-master_process off;
-daemon         off;
-
-events {
-}
-
-mail {
-    proxy_pass_error_message  on;
-    auth_http  http://127.0.0.1:8080/mail/auth;
-    xclient    off;
-
-    server {
-        listen     127.0.0.1:8025;
-        protocol   smtp;
-        smtp_auth  login plain none;
-    }
-}
-
-http {
-    %%TEST_GLOBALS_HTTP%%
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  localhost;
-
-        location = /mail/auth {
-            set $reply ERROR;
-
-            if ($http_auth_smtp_to ~ example.com) {
-                set $reply OK;
-            }
-
-            set $userpass "$http_auth_user:$http_auth_pass";
-            if ($userpass ~ '^test@example.com:secret$') {
-                set $reply OK;
-            }
-
-            add_header Auth-Status $reply;
-            add_header Auth-Server 127.0.0.1;
-            add_header Auth-Port 8026;
-            add_header Auth-Wait 1;
-            return 204;
-        }
-    }
-}
-
-EOF
-
-###############################################################################
-
-my $s = Test::Nginx::SMTP->new();
-$s->check(qr/^220 /, "greeting");
-
-$s->send('EHLO example.com');
-$s->check(qr/^250 /, "ehlo");
-
-$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0bad", ''));
-$s->check(qr/^5.. /, 'auth plain with bad password');
-
-$s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
-$s->authok('auth plain');
-
-# We are talking to backend from this point
-
-$s->send('MAIL FROM:<test@example.com> SIZE=100');
-$s->ok('mail from after auth');
-
-$s->send('RSET');
-$s->ok('rset');
-
-$s->send('MAIL FROM:<test@xn--e1afmkfd.xn--80akhbyknj4f> SIZE=100');
-$s->ok("idn mail from (example.test in russian)");
-
-$s->send('QUIT');
-$s->ok("quit");
-
-# Try auth login in simple form
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('EHLO example.com');
-$s->read();
-
-$s->send('AUTH LOGIN');
-$s->check(qr/^334 VXNlcm5hbWU6/, 'auth login simple username challenge');
-$s->send(encode_base64('test@example.com', ''));
-$s->check(qr/^334 UGFzc3dvcmQ6/, 'auth login simple password challenge');
-$s->send(encode_base64('secret', ''));
-$s->authok('auth login simple');
-
-# Try auth plain with username.  Details:
-#
-# [MS-XLOGIN]: SMTP Protocol AUTH LOGIN Extension Specification
-# http://download.microsoft.com/download/5/D/D/5DD33FDF-91F5-496D-9884-0A0B0EE698BB/%5BMS-XLOGIN%5D.pdf
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('EHLO example.com');
-$s->read();
-
-$s->send('AUTH LOGIN ' . encode_base64('test@example.com', ''));
-$s->check(qr/^334 UGFzc3dvcmQ6/, 'auth login with username password challenge');
-$s->send(encode_base64('secret', ''));
-$s->authok('auth login with username');
-
-# Try auth plain with pipelining
-
-TODO: {
-local $TODO = 'pipelining not in official nginx';
-local $SIG{__WARN__} = sub {};
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('EHLO example.com');
-$s->read();
-
-$s->send('INVALID COMMAND WITH ARGUMENTS' . CRLF
-	. 'RSET');
-$s->read();
-$s->ok('pipelined rset after invalid command');
-
-$s->send('AUTH PLAIN '
-	. encode_base64("\0test\@example.com\0bad", '') . CRLF
-	. 'MAIL FROM:<test@example.com> SIZE=100');
-$s->read();
-$s->ok('mail from after failed pipelined auth');
-
-$s->send('AUTH PLAIN '
-	. encode_base64("\0test\@example.com\0secret", '') . CRLF
-	. 'MAIL FROM:<test@example.com> SIZE=100');
-$s->read();
-$s->ok('mail from after pipelined auth');
-
-}
-
-# Try auth none
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('EHLO example.com');
-$s->read();
-
-$s->send('MAIL FROM:<test@example.com> SIZE=100');
-$s->ok('auth none - mail from');
-
-$s->send('RCPT TO:<test@example.com>');
-$s->ok('auth none - rcpt to');
-
-$s->send('RSET');
-$s->ok('auth none - rset, should go to backend');
-
-# Auth none with pipelining
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('EHLO example.com');
-$s->read();
-
-$s->send('MAIL FROM:<test@example.com> SIZE=100' . CRLF
-	. 'RCPT TO:<test@example.com>' . CRLF
-	. 'RSET');
-
-$s->ok('pipelined mail from');
-
-TODO: {
-local $TODO = 'pipelining not in official nginx';
-local $SIG{__WARN__} = sub {};
-
-$s->ok('pipelined rcpt to');
-$s->ok('pipelined rset');
-
-}
-
-# Connection must stay even if error returned to rcpt to command
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-$s->send('EHLO example.com');
-$s->read();
-
-$s->send('MAIL FROM:<test@example.com> SIZE=100');
-$s->read(); # skip mail from reply
-
-$s->send('RCPT TO:<example.com>');
-$s->check(qr/^5.. /, "bad rcpt to");
-
-$s->send('RCPT TO:<test@example.com>');
-$s->ok('good rcpt to');
-
-# Make sure command splitted into many packets processed correctly
-
-$s = Test::Nginx::SMTP->new();
-$s->read();
-
-log_out('HEL');
-$s->print('HEL');
-$s->send('O example.com');
-$s->ok('splitted command');
-
-###############################################################################
--- a/ssi-include-big.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for nginx ssi bug with big includes.
-
-###############################################################################
-
-use warnings;
-use strict;
-
-use Test::More;
-
-BEGIN { use FindBin; chdir($FindBin::Bin); }
-
-use lib 'lib';
-use Test::Nginx qw/ :DEFAULT :gzip /;
-
-###############################################################################
-
-select STDERR; $| = 1;
-select STDOUT; $| = 1;
-
-my $t = Test::Nginx->new()->has(qw/http ssi rewrite gzip proxy/)->plan(8);
-
-$t->write_file_expand('nginx.conf', <<'EOF');
-
-%%TEST_GLOBALS%%
-
-master_process off;
-daemon         off;
-
-events {
-}
-
-http {
-    %%TEST_GLOBALS_HTTP%%
-
-    output_buffers  2 512;
-    ssi on;
-    gzip on;
-
-    server {
-        listen       127.0.0.1:8080;
-        server_name  localhost;
-
-        location /proxy/ {
-            proxy_pass http://127.0.0.1:8080/local/;
-        }
-        location = /local/blah {
-            return 204;
-        }
-    }
-}
-
-EOF
-
-$t->write_file('c1.html', 'X' x 1023);
-$t->write_file('c2.html', 'X' x 1024);
-$t->write_file('c3.html', 'X' x 1025);
-$t->write_file('test1.html', '<!--#include virtual="/proxy/blah" -->'
-	. '<!--#include virtual="/c1.html" -->');
-$t->write_file('test2.html', '<!--#include virtual="/proxy/blah" -->'
-	. '<!--#include virtual="/c2.html" -->');
-$t->write_file('test3.html', '<!--#include virtual="/proxy/blah" -->'
-	. '<!--#include virtual="/c3.html" -->');
-$t->write_file('test4.html', '<!--#include virtual="/proxy/blah" -->'
-	. ('X' x 1025));
-
-$t->run();
-
-###############################################################################
-
-my $t1 = http_gzip_request('/test1.html');
-ok(defined $t1, 'small included file (less than output_buffers)');
-http_gzip_like($t1, qr/^X{1023}\Z/, 'small included file content');
-
-my $t2 = http_gzip_request('/test2.html');
-ok(defined $t2, 'small included file (equal to output_buffers)');
-http_gzip_like($t2, qr/^X{1024}\Z/, 'small included file content');
-
-my $t3 = http_gzip_request('/test3.html');
-ok(defined $t3, 'big included file (more than output_buffers)');
-http_gzip_like($t3, qr/^X{1025}\Z/, 'big included file content');
-
-my $t4 = http_gzip_request('/test4.html');
-ok(defined $t4, 'big ssi main file');
-http_gzip_like($t4, qr/^X{1025}\Z/, 'big ssi main file content');
-
-###############################################################################
--- a/ssi-waited.t	Mon Feb 21 14:26:27 2011 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-#!/usr/bin/perl
-
-# (C) Maxim Dounin
-
-# Tests for nginx ssi module, waited subrequests.
-
-###############################################################################
-
-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 ssi/)->plan(2);
-
-$t->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 / {
-            ssi on;
-        }
-    }
-}
-
-EOF
-
-$t->write_file('index.html', 'x<!--#include virtual="/first.html" -->' .
-	'x<!--#include virtual="/second.html" -->x');
-$t->write_file('first.html', 'FIRST');
-$t->write_file('second.html',
-	'<!--#include virtual="/waited.html" wait="yes"-->xSECOND');
-$t->write_file('waited.html', 'WAITED');
-
-$t->run();
-
-###############################################################################
-
-like(http_get('/'), qr/^xFIRSTxWAITEDxSECONDx$/m, 'waited non-active');
-
-like(`grep -F '[alert]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no alerts');
-
-###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ssi_include_big.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for nginx ssi bug with big includes.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More;
+
+BEGIN { use FindBin; chdir($FindBin::Bin); }
+
+use lib 'lib';
+use Test::Nginx qw/ :DEFAULT :gzip /;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+my $t = Test::Nginx->new()->has(qw/http ssi rewrite gzip proxy/)->plan(8);
+
+$t->write_file_expand('nginx.conf', <<'EOF');
+
+%%TEST_GLOBALS%%
+
+master_process off;
+daemon         off;
+
+events {
+}
+
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    output_buffers  2 512;
+    ssi on;
+    gzip on;
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  localhost;
+
+        location /proxy/ {
+            proxy_pass http://127.0.0.1:8080/local/;
+        }
+        location = /local/blah {
+            return 204;
+        }
+    }
+}
+
+EOF
+
+$t->write_file('c1.html', 'X' x 1023);
+$t->write_file('c2.html', 'X' x 1024);
+$t->write_file('c3.html', 'X' x 1025);
+$t->write_file('test1.html', '<!--#include virtual="/proxy/blah" -->'
+	. '<!--#include virtual="/c1.html" -->');
+$t->write_file('test2.html', '<!--#include virtual="/proxy/blah" -->'
+	. '<!--#include virtual="/c2.html" -->');
+$t->write_file('test3.html', '<!--#include virtual="/proxy/blah" -->'
+	. '<!--#include virtual="/c3.html" -->');
+$t->write_file('test4.html', '<!--#include virtual="/proxy/blah" -->'
+	. ('X' x 1025));
+
+$t->run();
+
+###############################################################################
+
+my $t1 = http_gzip_request('/test1.html');
+ok(defined $t1, 'small included file (less than output_buffers)');
+http_gzip_like($t1, qr/^X{1023}\Z/, 'small included file content');
+
+my $t2 = http_gzip_request('/test2.html');
+ok(defined $t2, 'small included file (equal to output_buffers)');
+http_gzip_like($t2, qr/^X{1024}\Z/, 'small included file content');
+
+my $t3 = http_gzip_request('/test3.html');
+ok(defined $t3, 'big included file (more than output_buffers)');
+http_gzip_like($t3, qr/^X{1025}\Z/, 'big included file content');
+
+my $t4 = http_gzip_request('/test4.html');
+ok(defined $t4, 'big ssi main file');
+http_gzip_like($t4, qr/^X{1025}\Z/, 'big ssi main file content');
+
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ssi_waited.t	Fri Mar 04 16:07:15 2011 +0300
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for nginx ssi module, waited subrequests.
+
+###############################################################################
+
+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 ssi/)->plan(2);
+
+$t->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 / {
+            ssi on;
+        }
+    }
+}
+
+EOF
+
+$t->write_file('index.html', 'x<!--#include virtual="/first.html" -->' .
+	'x<!--#include virtual="/second.html" -->x');
+$t->write_file('first.html', 'FIRST');
+$t->write_file('second.html',
+	'<!--#include virtual="/waited.html" wait="yes"-->xSECOND');
+$t->write_file('waited.html', 'WAITED');
+
+$t->run();
+
+###############################################################################
+
+like(http_get('/'), qr/^xFIRSTxWAITEDxSECONDx$/m, 'waited non-active');
+
+like(`grep -F '[alert]' ${\($t->testdir())}/error.log`, qr/^$/s, 'no alerts');
+
+###############################################################################