File: proxy_header_test

package info (click to toggle)
sniproxy 0.6.1%2Bgit20240321-0.2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 644 kB
  • sloc: ansic: 5,594; perl: 1,673; sh: 237; makefile: 131
file content (136 lines) | stat: -rwxr-xr-x 3,579 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env perl

use strict;
use warnings;
use File::Basename;
use lib dirname (__FILE__);
use TestUtils;
use TestHTTPD;
use File::Temp;
use IO::Socket::INET;

sub proxy {
    my $config = shift;

    exec(@_, '../src/sniproxy', '-f', '-c', $config);
}

sub make_proxy_config($$$) {
    my $proxy_port = shift;
    my $httpd_port = shift;
    my $httpd2_port = shift;

    my ($fh, $filename) = File::Temp::tempfile();
    my ($unused, $logfile) = File::Temp::tempfile();

    # Write out a test config file
    print $fh <<END;
# Minimal fallback test configuration

listen 127.0.0.1 $proxy_port {
    proto http
    access_log $logfile
}

table {
    proxy-protocol.local 127.0.0.1:$httpd2_port proxy_protocol
    localhost 127.0.0.1:$httpd_port
}
END

    close ($fh);

    return $filename;
}

sub worker($$$$) {
    my ($hostname, $path, $port, $requests) = @_;

    for (my $i = 0; $i < $requests; $i++) {
        system('curl',
                '-s', '-S',
                '--fail',
                '-H', "Host: $hostname",
                '-o', '/dev/null',
                "http://localhost:$port/$path");

        if ($? == -1) {
            die "failed to execute: $!\n";
        } elsif ($? & 127) {
            printf STDERR "child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without';
            exit 255;
        } elsif ($? >> 8) {
            exit $? >> 8;
        }
    }
    # Success
    exit 0;
}

sub valid_port($) {
    my $port = shift;

    return $port eq int($port) && $port > 0 && $port <= 65535;
}

sub main {
    my $proxy_port = $ENV{SNI_PROXY_PORT} || 8080;
    my $httpd_port = $ENV{TEST_HTTPD_PORT} || 8081;
    my $httpd2_port = $ENV{TEST_HTTPD_PORT2} || 8082;
    my $workers = $ENV{WORKERS} || 10;
    my $iterations = $ENV{ITERATIONS} || 10;
    my $local_httpd = $ENV{LOCAL_HTTPD_PORT};

    my $config = make_proxy_config($proxy_port, $local_httpd || $httpd_port, $httpd2_port);
    my $proxy_pid = start_child('server', \&proxy, $config, @ARGV);
    my $httpd_pid = start_child('server', \&TestHTTPD::httpd, port => $httpd_port) unless $local_httpd;
    my $httpd2_pid = start_child('server', \&TestHTTPD::httpd, port => $httpd2_port, parser => sub {
        my $sock = shift;

        my $status = 500;

        for (my $i = 0; my $line = $sock->getline(); $i++) {
            if ($i == 0 && $line =~ m/\APROXY (\S+) (\S+) (\S+) (\S+) (\S+)\r\n\z/ &&
                $1 eq 'TCP4' &&
                $2 eq '127.0.0.1' && $3 eq '127.0.0.1' &&
                valid_port($4) && valid_port($5)) {
                $status = 200;
            }

            # Wait for blank line indicating the end of the request
            last if $line eq "\r\n";
        }

        return $status;
    });

    # Wait for proxy to load and parse config
    wait_for_port(port => $httpd_port);
    wait_for_port(port => $httpd2_port);
    wait_for_port(port => $proxy_port);

    for (my $i = 0; $i < $workers; $i++) {
        my $req_hostname = ($i % 2) ? 'proxy-protocol.local' : 'localhost';
        start_child('worker', \&worker, $req_hostname, '', $proxy_port, $iterations);
    }

    # Wait for all our children to finish
    wait_for_type('worker');

    # Give the proxy a second to flush buffers and close server connections
    sleep 1;

    # Orderly shutdown of the server
    kill 15, $proxy_pid;
    kill 15, $httpd_pid unless $local_httpd;
    kill 15, $httpd2_pid;
    sleep 1;

    # Delete our test configuration
    unlink($config);

    # Kill off any remaining children
    reap_children();
}

main();