view userid.t @ 1905:f35824e75b66

Tests: fixed reading QUIC streams on Perl < 5.24. The parse_stream() routine has had a missing explicit return if there were no streams received. In Perl < 5.24 this used to return no value, or an empty array in the list context. In modern Perl this returns an empty value, or an array of 1 element, which made the check for last index of the returned array work rather by accident. The fix is to return explicitly and to check the array size in callers instead.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 06 Jun 2023 18:50:07 +0400
parents 144c6ce732e4
children
line wrap: on
line source

#!/usr/bin/perl

# (C) Andrey Zelenkov
# (C) Nginx, Inc.

# Tests for userid filter module.

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

use warnings;
use strict;

use Test::More;

use Config;
use MIME::Base64;
use Time::Local;

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 userid map unix/);

$t->write_file_expand('nginx.conf', <<'EOF');

%%TEST_GLOBALS%%

daemon off;

events {
}

http {
    %%TEST_GLOBALS_HTTP%%

    map $args $uid_reset {
        default      0;
        value        1;
        log          log;
    }

    server {
        listen       127.0.0.1:8080;
        listen       [::1]:%%PORT_8080%%;
        listen       unix:%%TESTDIR%%/unix.sock;
        server_name  localhost;

        add_header X-Got $uid_got;
        add_header X-Reset $uid_reset;
        add_header X-Set $uid_set;
        userid on;

        location / {
            error_log %%TESTDIR%%/error.log debug;
            error_log %%TESTDIR%%/error_reset.log info;
        }

        location /name {
            userid_name test;
        }

        location /path {
            userid_path /0123456789;

            location /path/r {
                userid_path /9876543210;
            }
        }

        location /domain {
            userid_domain test.domain;
        }

        location /mark_off {
            userid_mark off;
        }
        location /mark_eq {
            userid_mark =;
        }
        location /mark_let {
            userid_mark t;
        }
        location /mark_num {
            userid_mark 9;
        }

        location /expires_time {
            add_header X-Msec $msec;
            userid_expires 100;
        }
        location /expires_max {
            userid_expires max;

            location /expires_max/off {
                userid_expires off;
            }
        }
        location /expires_off {
            userid_expires off;
        }

        location /p3p {
            userid_p3p policyref="/w3c/p3p.xml";
        }

        location /service {
            userid_service 65534;
        }

        location /cv1 {
            userid v1;
            userid_mark t;
        }

        location /ip6 {
            userid off;
            proxy_pass http://[::1]:%%PORT_8080%%/;
        }

        location /unix {
            userid off;
            proxy_pass http://unix:%%TESTDIR%%/unix.sock:/;
        }

        location /clog {
            userid log;
        }

        location /coff {
            userid off;
        }
    }
}

EOF

$t->write_file('index.html', '');
$t->write_file('expires_time', '');
$t->write_file('service', '');
$t->write_file('cv1', '');
$t->write_file('clog', '');
$t->write_file('coff', '');
$t->try_run('no inet6 support')->plan(35);

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

# userid

like(http_get('/'), qr/Set-Cookie:/, 'cookie on');
like(http_get('/cv1'), qr/Set-Cookie:/, 'cookie v1');
unlike(http_get('/clog'), qr/Set-Cookie:/, 'cookie log');
unlike(http_get('/coff'), qr/Set-Cookie:/, 'cookie off');

# default

my %cookie = get_cookie('/');
isnt($cookie{'uid'}, undef, 'name default');
is($cookie{'path'}, '/', 'path default');
is($cookie{'domain'}, undef, 'domain default');
is($cookie{'expires'}, undef, 'expires default');
like($cookie{'uid'}, '/\w+={0,2}$/', 'mark default');
unlike(http_get('/'), qr/^P3P/m, 'p3p default');
like(http_get('/'), qr/X-Reset: 0/, 'uid reset variable default');

# name, path, domain and p3p

isnt(get_cookie('/name', 'test'), undef, 'name');
is(get_cookie('/path', 'path'), '/0123456789', 'path');
is(get_cookie('/domain', 'domain'), 'test.domain', 'domain');
like(http_get('/p3p'), qr!P3P: policyref="/w3c/p3p.xml"!, 'p3p');

# mark

like(get_cookie('/mark_off', 'uid'), '/\w+={0,2}$/', 'mark off');
like(get_cookie('/mark_eq', 'uid'), '/==$/', 'mark equal');
like(get_cookie('/mark_let', 'uid'), '/t=$/', 'mark letter');
like(get_cookie('/mark_num', 'uid'), '/9=$/', 'mark number');

# expires

my $r = http_get('/expires_time');
my ($t1) = $r =~ /X-Msec: (\d+)/;
is(expires2timegm(cookie($r, 'expires')), $t1 + 100, 'expires time');
is(get_cookie('/expires_max', 'expires'), 'Thu, 31-Dec-37 23:55:55 GMT',
	'expires max');
is(get_cookie('/expires_off', 'expires'), undef, 'expires off');

# redefinition

unlike(http_get('/expires_max/off'), qr/expires/, 'redefine expires');
like(http_get('/path/r'), qr!/9876543210!, 'redefine path');

# requests

$r = http_get('/');
my ($uid) = uid_set($r);
isnt($uid, undef, 'uid set variable');

$r = send_uid('/', cookie($r, 'uid'));
is(uid_got($r), $uid, 'uid got variable');
unlike($r, qr/Set-Cookie:/, 'same path request');

$r = send_uid('/coff', $uid);
unlike($r, qr/Set-Cookie:/, 'other path request');

$r = send_uid('/?value', $uid);
like($r, qr/Set-Cookie:/, 'uid reset variable value');

# service

is(substr(uid_set(http_get('/cv1')), 0, 8), '00000000', 'service default v1');

my $bigendian = $Config{byteorder} =~ '1234' ? 0 : 1;
my $addr = $bigendian ? "7F000001" : "0100007F";
is(substr(uid_set(http_get('/')), 0, 8), $addr, 'service default v2');

$addr = $bigendian ? "0000FFFE" : "FEFF0000";
is(substr(uid_set(http_get('/service')), 0, 8), $addr, 'service custom');

$addr = $bigendian ? "00000001" : "01000000";
is(substr(uid_set(http_get('/ip6')), 0, 8), $addr, 'service ipv6');

is(substr(uid_set(http_get('/unix')), 0, 8), "00000000", 'service unix');

# reset log

send_uid('/?log', cookie($r, 'uid'));

$t->stop();

like($t->read_file('error_reset.log'),
	'/userid cookie "uid=\w+" was reset/m', 'uid reset variable log');

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

sub cookie {
	my ($r, $key) = @_;
	my %cookie;

	$r =~ /(Set-Cookie:[^\x0d]*).*\x0d\x0a?\x0d/ms;
	if ($1) {
		%cookie = $1 =~ /(\w+)=([^;]+)/g;
	}

	return $cookie{$key} if defined $key;
	return %cookie;
}

sub get_cookie {
	my ($url, $key) = @_;
	return cookie(http_get($url), $key);
}

sub expires2timegm {
	my ($e) = @_;
	my %months = (Jan => 0, Feb => 1, Mar => 2, Apr => 3, May =>4, Jun => 5,
		Jul => 6, Aug => 7, Sep => 8, Oct => 9, Nov => 10, Dec => 11);

	my ($w, $date, $time) = split(" ", $e);
	my ($day, $month, $year) = split("-", $date);
	my ($hour, $min, $sec) = split(":", $time);

	return timegm($sec, $min, $hour, $day, $months{$month}, $year);
}

sub uid_set {
	my ($r) = @_;
	my ($uid) = $r =~ /X-Set: uid=(.*)\n/m;
	return $uid;
}

sub uid_got {
	my ($r) = @_;
	my ($uid) = $r =~ /X-Got: uid=(.*)\n/m;
	return $uid;
}

sub send_uid {
	my ($url, $uid) = @_;
	return http(<<EOF);
GET $url HTTP/1.0
Host: localhost
Cookie: uid=$uid

EOF
}

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