Tests: some generic code and ssi tests.
Move generic code to _common.pm and add test for ssi big includes.
diff --git a/_common.pm b/_common.pm
new file mode 100644
index 0000000..482c88c
--- /dev/null
+++ b/_common.pm
@@ -0,0 +1,164 @@
+package _common;
+
+# (C) Maxim Dounin
+
+# Generict module for nginx tests.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use base qw/ Exporter /;
+
+our @EXPORT = qw/ start_nginx smtp_connect smtp_send smtp_read smtp_check
+ smtp_ok log_in log_out CRLF http /;
+
+###############################################################################
+
+use Test::More;
+use File::Temp qw/ tempdir /;
+use IO::Socket;
+
+use constant CRLF => "\x0D\x0A";
+
+our $testdir;
+our $s;
+
+###############################################################################
+
+# Create temp directory and run nginx instance.
+
+sub start_nginx {
+ my ($conf) = @_;
+
+ $testdir = tempdir('nginx-test-XXXXXXXXXX', TMPDIR => 1, CLEANUP => 1)
+ or die "Can't create temp directory: $!\n";
+
+ system("cat $conf | sed 's!%%TESTDIR%%!$testdir!g' "
+ . "> $testdir/nginx.conf");
+
+ my $pid = fork();
+ die "Unable to fork(): $!\n" unless defined $pid;
+
+ if ($pid == 0) {
+ exec('../nginx/objs/nginx', '-c', "$testdir/nginx.conf", '-g',
+ "pid $testdir/nginx.pid; "
+ . "error_log $testdir/nginx-error.log debug;")
+ or die "Unable to exec(): $!\n";
+ }
+
+ # wait for nginx to start
+
+ sleep 1;
+}
+
+sub stop_nginx {
+ # terminate nginx by SIGTERM
+ kill 15, `cat $testdir/nginx.pid`;
+ wait;
+}
+
+END {
+ stop_nginx();
+}
+
+###############################################################################
+
+sub log_out {
+ my ($msg) = @_;
+ $msg =~ s/^/# >> /gm;
+ $msg .= "\n" unless $msg =~ /\n\Z/;
+ print $msg;
+}
+
+sub log_in {
+ my ($msg) = @_;
+ $msg =~ s/^/# << /gm;
+ $msg =~ s/([\x00-\x1f\x7f-])/sprintf('\\x%02x', ord($1)) . (($1 eq "\n") ? "\n" : '')/gmxe;
+ $msg .= "\n" unless $msg =~ /\n\Z/;
+ print $msg;
+}
+
+###############################################################################
+
+sub http {
+ my ($request) = @_;
+ my $reply;
+ eval {
+ local $SIG{ALRM} = sub { die "alarm\n" };
+ alarm(2);
+ my $s = IO::Socket::INET->new(
+ Proto => 'tcp',
+ PeerHost => 'localhost:8080'
+ );
+ log_out($request);
+ $s->print($request);
+ local $/;
+ $reply = $s->getline();
+ log_in($reply);
+ alarm(0);
+ };
+ alarm(0);
+ if ($@) {
+ log_in('(timeout)');
+ return undef;
+ }
+ return $reply;
+}
+
+###############################################################################
+
+sub smtp_connect {
+ $s = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => "localhost",
+ PeerPort => 10025,
+ @_
+ )
+ or die "Can't connect to nginx: $!\n";
+
+ $s->autoflush(1);
+
+ return $s;
+}
+
+sub smtp_send {
+ my ($cmd) = @_;
+ log_out($cmd);
+ $s->print($cmd . CRLF);
+}
+
+sub smtp_read {
+ my ($regex, $name) = @_;
+ eval {
+ alarm(2);
+ local $SIG{ALRM} = sub { die "alarm\n" };
+ while (<$s>) {
+ log_in($_);
+ next if m/^\d\d\d-/;
+ last;
+ }
+ alarm(0);
+ };
+ alarm(0);
+ if ($@) {
+ return undef;
+ }
+ return $_;
+}
+
+sub smtp_check {
+ my ($regex, $name) = @_;
+ like(smtp_read(), $regex, $name);
+}
+
+sub smtp_ok {
+ smtp_check(qr/^2\d\d /, @_);
+}
+
+###############################################################################
+
+1;
+
+###############################################################################
diff --git a/smtp.t b/smtp.t
index 571693d..318f6f4 100644
--- a/smtp.t
+++ b/smtp.t
@@ -11,41 +11,16 @@
use Test::More tests => 28;
-use File::Temp qw/ tempdir /;
-use IO::Socket;
use MIME::Base64;
-use constant CRLF => "\x0D\x0A";
+use _common;
+
+###############################################################################
select STDERR; $| = 1;
select STDOUT; $| = 1;
-###############################################################################
-
-# Create temp directory and run nginx instance.
-
-my $tempdir = tempdir('nginx-test-XXXXXXXXXX', TMPDIR => 1, CLEANUP => 1)
- or die "Can't create temp directory: $!\n";
-
-my $pid = fork();
-die "Unable to fork(): $!\n" unless defined $pid;
-
-if ($pid == 0) {
- exec('../nginx/objs/nginx', '-c', 'smtp.conf', '-g',
- "pid $tempdir/nginx.pid; error_log $tempdir/nginx-error.log info;")
- or die "Unable to exec(): $!\n";
- print "# child after exec - not reached\n";
-}
-
-END {
- # terminate nginx by SIGTERM
- kill 15, $pid;
- wait;
-}
-
-# Give nginx some time to start.
-
-sleep 1;
+start_nginx('smtp.conf');
###############################################################################
@@ -171,67 +146,3 @@
ok($s->eof(), "session have to be closed");
###############################################################################
-
-sub log_out {
- my ($msg) = @_;
- $msg =~ s/^/# >> /gm;
- $msg .= "\n" unless $msg =~ /\n\Z/;
- print $msg;
-}
-
-sub log_in {
- my ($msg) = @_;
- $msg =~ s/\x0d/\\x0d/gm;
- $msg =~ s/\x0a/\\x0a/gm;
- print '# << ' . $msg . "\n";
-}
-
-sub smtp_connect {
- my $s = IO::Socket::INET->new(
- Proto => "tcp",
- PeerAddr => "localhost",
- PeerPort => 10025,
- @_
- )
- or die "Can't connect to nginx: $!\n";
-
- $s->autoflush(1);
-
- return $s;
-}
-
-sub smtp_send {
- my ($cmd) = @_;
- log_out($cmd);
- $s->print($cmd . CRLF);
-}
-
-sub smtp_read {
- my ($regex, $name) = @_;
- eval {
- alarm(2);
- local $SIG{ALRM} = sub { die "alarm\n" };
- while (<$s>) {
- log_in($_);
- next if m/^\d\d\d-/;
- last;
- }
- alarm(0);
- };
- alarm(0);
- if ($@) {
- return undef;
- }
- return $_;
-}
-
-sub smtp_check {
- my ($regex, $name) = @_;
- like(smtp_read(), $regex, $name);
-}
-
-sub smtp_ok {
- smtp_check(qr/^2\d\d /, @_);
-}
-
-###############################################################################
diff --git a/ssi-include-big.conf b/ssi-include-big.conf
new file mode 100644
index 0000000..886be1f
--- /dev/null
+++ b/ssi-include-big.conf
@@ -0,0 +1,33 @@
+# Config for ssi-include-big.t test.
+
+worker_processes 1;
+
+master_process off;
+daemon off;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ access_log off;
+ root %%TESTDIR%%;
+
+ output_buffers 2 512;
+ ssi on;
+ gzip on;
+ gzip_http_version 1.0;
+
+
+ server {
+ listen 8080;
+ server_name localhost;
+
+ location /proxy/ {
+ proxy_pass http://localhost:8080/local/;
+ }
+ location = /local/blah {
+ return 204;
+ }
+ }
+}
diff --git a/ssi-include-big.t b/ssi-include-big.t
new file mode 100644
index 0000000..1e82a65
--- /dev/null
+++ b/ssi-include-big.t
@@ -0,0 +1,74 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for nginx ssi bug with big includes.
+
+###############################################################################
+
+use warnings;
+use strict;
+
+use Test::More tests => 3;
+
+use _common;
+use Compress::Zlib;
+
+###############################################################################
+
+select STDERR; $| = 1;
+select STDOUT; $| = 1;
+
+start_nginx('ssi-include-big.conf');
+
+write_file('c1.html', 'X' x 1023);
+write_file('c2.html', 'X' x 1024);
+write_file('c3.html', 'X' x 1025);
+write_file('test1.html', '<!--#include virtual="/proxy/blah" -->' . "\n"
+ . '<!--#include virtual="/c1.html" -->');
+write_file('test2.html', '<!--#include virtual="/proxy/blah" -->' . "\n"
+ . '<!--#include virtual="/c2.html" -->');
+write_file('test3.html', '<!--#include virtual="/proxy/blah" -->' . "\n"
+ . '<!--#include virtual="/c3.html" -->');
+
+###############################################################################
+
+my $t1 = http_gzip_request('/test1.html');
+like($t1, qr/X{1023}/, 'small included file (less than output_buffers)');
+
+my $t2 = http_gzip_request('/test2.html');
+like($t2, qr/X{1024}/, 'small included file (equal to output_buffers)');
+
+my $t3 = http_gzip_request('/test3.html');
+like($t3, qr/X{1025}/, 'big included file (more than output_buffers)');
+
+###############################################################################
+
+sub http_gzip_request {
+ my ($url) = @_;
+ return `GET -t 1 -H 'Accept-Encoding: gzip' http://localhost:8080$url | gunzip -c`;
+=pod
+
+ my $r = http(<<EOF);
+GET $url HTTP/1.0
+Host: localhost
+Connection: close
+Accept-Encoding: gzip
+
+EOF
+ return undef unless defined $r;
+ return undef unless $r =~ m/\x0d\x0a\x0d\x0a(.*)/ms;
+ return Compress::Zlib::memGunzip(my $b = $1);
+=cut
+}
+
+sub write_file {
+ my ($name, $content) = @_;
+
+ open F, '>' . $_common::testdir . '/' . $name
+ or die "Can't create $name: $!";
+ print F $content;
+ close F;
+}
+
+###############################################################################