view proxy_xar.t @ 1951:1867428f1673

Tests: fixed h3_limit_req.t spurious failures. In the "reset stream - cancellation" test, HTTP/3 stream is closed without sending the request body when the request is waiting in the limit_req module, and this results in error 444. However, when the request is received with some minor delay due to system load, it is not delayed by limit_req, and the stream is closed during reading the request body, which results in error 400 instead, breaking the test. Fix is to introduce yet another request before the "reset stream" test, so the stream in question is always delayed by limit_req.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 14 Mar 2024 02:25:49 +0300
parents 882267679006
children
line wrap: on
line source

#!/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(16);

$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;

        # catch safe and unhandled unsafe URIs,
        # bypassed with redirect to named location
        if ($upstream_http_x_accel_redirect) {
            return 200 "xar: $upstream_http_x_accel_redirect uri: $uri
                        method: $request_method";
        }

        location /proxy {
            proxy_pass http://127.0.0.1:8080/return-xar;
        }
        location /return-xar {
            add_header  X-Accel-Redirect     $arg_xar;

            # 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;
        }
        location @named {
            return 200 "named xar: $upstream_http_x_accel_redirect uri: $uri";
        }
    }
}

EOF

$t->run();

###############################################################################

my $r = http_get('/proxy?xar=/index.html');
like($r, qr/xar: \/index.html uri: \/index.html/, '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');

like(http_post('/proxy?xar=/index.html'), qr/method: GET/,
	'X-Accel-Redirect method name');

# escaped characters

like(http_get('/proxy?xar=/foo?bar'), qr/200 OK.*xar: \/foo\?bar/s,
	'X-Accel-Redirect value unchanged');
unlike(http_get('/proxy?xar=..'), qr/200 OK/,
	'X-Accel-Redirect unsafe dotdot');
unlike(http_get('/proxy?xar=../foo'), qr/200 OK/,
	'X-Accel-Redirect unsafe dotdotsep');
unlike(http_get('/proxy?xar=/foo/..'), qr/200 OK/,
	'X-Accel-Redirect unsafe sepdotdot');
unlike(http_get('/proxy?xar=/foo/.%2e'), qr/200 OK/,
	'X-Accel-Redirect unsafe unescaped');
like(http_get('/proxy?xar=/foo%20bar'), qr/uri: \/foo bar/,
	'X-Accel-Redirect unescaped');

like(http_get('/proxy?xar=@named'),
	qr!200 OK.*named xar: \@named uri: /proxy!s, 'in named location');

###############################################################################

sub http_post {
	my ($url) = @_;
	http(<<EOF);
POST $url HTTP/1.0
Host: localhost

EOF
}

###############################################################################