changeset 509:f135127e97af

Tests: various proxy_pass + if tests.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 08 Dec 2014 20:29:43 +0300
parents 4ac60aad723e
children 4892d701d558
files proxy_if.t
diffstat 1 files changed, 261 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/proxy_if.t
@@ -0,0 +1,261 @@
+#!/usr/bin/perl
+
+# (C) Maxim Dounin
+
+# Tests for http proxy module related to use with the "if" directive.
+# See http://wiki.nginx.org/IfIsEvil for more details.
+
+###############################################################################
+
+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 http_ssl/)->plan(15);
+
+$t->write_file_expand('nginx.conf', <<'EOF');
+
+%%TEST_GLOBALS%%
+
+daemon off;
+
+events {
+}
+
+http {
+    %%TEST_GLOBALS_HTTP%%
+
+    server {
+        listen       127.0.0.1:8080;
+        server_name  localhost;
+
+        location / {
+            proxy_pass http://127.0.0.1:8081/;
+        }
+
+        # request will be sent to backend without uri changed
+        # to '/' due to if
+
+        location /proxy-pass-uri {
+            proxy_pass http://127.0.0.1:8081/replacement;
+
+            if ($arg_if) {
+                # nothing
+            }
+
+            location /proxy-pass-uri/inner {
+                # no proxy_pass here, static
+
+                if ($arg_if) {
+                    # nothing
+                }
+            }
+        }
+
+        # same as the above, but there is a special handling
+        # in configuration merge; it may do wrong things though
+
+        location /proxy-pass-uri-lmt {
+            proxy_pass http://127.0.0.1:8081/replacement;
+
+            limit_except POST {
+                # nothing
+            }
+
+            location /proxy-pass-uri-lmt/inner {
+                # no proxy_pass here, static
+
+                limit_except POST {
+                    # nothing
+                }
+            }
+        }
+
+        location /proxy-pass-uri-lmt-different {
+            proxy_pass http://127.0.0.1:8081/replacement;
+
+            limit_except POST {
+                proxy_pass http://127.0.0.1:8081;
+            }
+        }
+
+        # segmentation fault in old versions,
+        # fixed to return 500 Internal Error in nginx 1.3.10
+
+        location /proxy-inside-if-crash {
+
+            set $true 1;
+
+            if ($true) {
+                # proxy_pass inside if
+                proxy_pass http://127.0.0.1:8081;
+            }
+
+            if ($true) {
+                # no handler here
+            }
+        }
+
+        # normal proxy_pass and proxy_pass with variables
+        # use distinct field, and inheritance should be mutually
+        # exclusive
+
+        location /variables {
+            proxy_pass http://127.0.0.1:8081/outer/$host;
+
+            if ($arg_if) {
+                proxy_pass http://127.0.0.1:8081;
+            }
+
+            location /variables/inner {
+                proxy_pass http://127.0.0.1:8081;
+            }
+        }
+
+        # ssl context shouldn't be inherited into nested
+        # locations with different proxy_pass, but should
+        # be correctly inherited into if's
+
+        location /ssl {
+            proxy_pass https://127.0.0.1:8082/outer;
+
+            if ($arg_if) {
+                # inherited from outer
+            }
+
+            location /ssl/inner {
+                proxy_pass http://127.0.0.1:8081;
+            }
+        }
+    }
+
+    server {
+        listen       127.0.0.1:8081;
+        listen       127.0.0.1:8082 ssl;
+        server_name  localhost;
+
+        ssl_certificate localhost.crt;
+        ssl_certificate_key localhost.key;
+
+        return 200 "uri:$uri\n";
+    }
+}
+
+EOF
+
+$t->write_file('openssl.conf', <<EOF);
+[ req ]
+default_bits = 2048
+encrypt_key = no
+distinguished_name = req_distinguished_name
+[ req_distinguished_name ]
+EOF
+
+my $d = $t->testdir();
+
+foreach my $name ('localhost') {
+	system('openssl req -x509 -new '
+		. "-config '$d/openssl.conf' -subj '/CN=$name/' "
+		. "-out '$d/$name.crt' -keyout '$d/$name.key' "
+		. ">>$d/openssl.out 2>&1") == 0
+		or die "Can't create certificate for $name: $!\n";
+}
+
+$t->run();
+
+###############################################################################
+
+like(http_get('/'), qr!uri:/$!, 'proxy request');
+
+like(http_get('/proxy-pass-uri'), qr!uri:/replacement$!,
+	'proxy_pass uri changed');
+
+TODO: {
+local $TODO = 'not yet';
+
+# due to missing information about an original location where
+# proxy_pass was specified, this used to pass request with
+# original unmodified uri
+
+like(http_get('/proxy-pass-uri?if=1'), qr!uri:/replacement$!,
+	'proxy_pass uri changed in if');
+
+}
+
+like(http_get('/proxy-pass-uri/inner'), qr!404 Not Found!,
+	'proxy_pass uri changed inner');
+like(http_get('/proxy-pass-uri/inner?if=1'), qr!404 Not Found!,
+	'proxy_pass uri changed inner in if');
+
+# limit_except
+
+like(http_get('/proxy-pass-uri-lmt'), qr!uri:/replacement$!,
+	'proxy_pass uri and limit_except');
+
+TODO: {
+local $TODO = 'not yet';
+
+# special handling of limit_except results in wrong handling
+# of requests in nested locations
+
+like(http_get('/proxy-pass-uri-lmt/inner'), qr!404 Not Found!,
+	'proxy_pass uri and limit_except, inner');
+
+}
+
+like(http_get('/proxy-pass-uri-lmt-different'),
+	qr!uri:/proxy-pass-uri-lmt-different!,
+	'proxy_pass and limit_except with different proxy_pass');
+
+# segmentation fault in old versions,
+# fixed to return 500 Internal Error in nginx 1.3.10
+
+like(http_get('/proxy-inside-if-crash'), qr!500 Internal Server Error!,
+	'proxy_pass inside if');
+
+# normal proxy_pass and proxy_pass with variables
+# use distinct field, and inheritance should be mutually
+# exclusive, see ticket #537
+
+like(http_get('/variables'), qr!uri:/outer!,
+	'proxy_pass variables');
+
+TODO: {
+local $TODO = 'not yet';
+
+like(http_get('/variables?if=1'), qr!uri:/variables!,
+	'proxy_pass variables if');
+like(http_get('/variables/inner'), qr!uri:/variables/inner!,
+	'proxy_pass variables nested');
+
+}
+
+# ssl context shouldn't be inherited into nested
+# locations with different proxy_pass, but should
+# be correctly inherited into if's
+
+like(http_get('/ssl'), qr!uri:/outer!,
+	'proxy_pass ssl');
+like(http_get('/ssl?if=1'), qr!uri:/outer!,
+	'proxy_pass ssl inside if');
+
+TODO: {
+local $TODO = 'not yet';
+
+like(http_get('/ssl/inner'), qr!uri:/ssl/inner!,
+	'proxy_pass nossl inside ssl');
+
+}
+
+###############################################################################