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
|
use strict;
use warnings;
use IO::Socket::INET;
use Net::EmptyPort qw(check_port empty_port);
use Test::More;
use t::Util;
plan skip_all => 'plackup not found'
unless prog_exists('plackup');
plan skip_all => 'Starlet not found'
unless system('perl -MStarlet /dev/null > /dev/null 2>&1') == 0;
# spawn upstream
my $upstream_port = empty_port();
my $upstream = spawn_server(
argv => [
qw(plackup -s Starlet --access-log /dev/null -p), $upstream_port, ASSETS_DIR . "/upstream.psgi",
],
is_ready => sub {
check_port($upstream_port);
},
);
sub silent_server {
return spawn_h2o(<< "EOT");
hosts:
default:
paths:
/:
proxy.reverse.url: http://127.0.0.1:$upstream_port/
proxy.websocket: ON
proxy.websocket.timeout: 1000
EOT
}
subtest "http/1.1" => sub {
my $server = silent_server();
plan skip_all => "curl not found"
unless prog_exists("curl");
my $resp = `curl --silent --insecure 'http://127.0.0.1:$server->{port}/index.txt'`;
is $resp, "hello\n";
};
sub doit {
my $conn = shift;
my $req = join(
"\r\n",
"GET /websocket/ HTTP/1.1",
"Connection: upgrade",
"Upgrade: websocket",
"Sec-Websocket-Key: abcde",
"Sec-Websocket-Version: 13",
"",
"",
);
is $conn->syswrite($req), length($req), "send request";
$conn->sysread(my $rbuf, 65536) > 0
or die "failed to read HTTP response";
like $rbuf, qr{^HTTP\/1\.1 101 }is;
like $rbuf, qr{\r\n\r\n$}is;
like $rbuf, qr{\r\nupgrade: websocket\r\n}is;
unlike $rbuf, qr{\r\nupgrade:.*\r\nupgrade:}is;
like $rbuf, qr{\r\nsec-websocket-accept: .*\r\n}is;
for my $i (1..10) {
my $msg = "hello world $i\n";
is $conn->syswrite($msg), length($msg), "write text ($i)";
is $conn->sysread($rbuf, 65536), length($msg), "read echo ($i)";
is $rbuf, $msg, "echo is correct ($i)";
}
$conn->close;
}
subtest "ws" => sub {
my $server = silent_server();
my $conn = IO::Socket::INET->new(
PeerHost => '127.0.0.1',
PeerPort => $server->{port},
Proto => 'tcp',
) or die "failed to connect to 127.0.0.1:$server->{port}:$!";
doit($conn);
};
subtest "wss" => sub {
my $server = silent_server();
eval q{use IO::Socket::SSL; 1}
or plan skip_all => "IO::Socket::SSL not found";
my $conn = IO::Socket::SSL->new(
PeerAddr => "127.0.0.1:$server->{tls_port}",
SSL_verify_mode => 0,
) or die "failed to connect via TLS to 127.0.0.1:$server->{tls_port}:". IO::Socket::SSL::errstr();
doit($conn);
};
subtest "logged-ws" => sub {
my $server = spawn_h2o(<< "EOT");
hosts:
default:
paths:
/:
proxy.reverse.url: http://127.0.0.1:$upstream_port/
proxy.websocket: ON
proxy.websocket.timeout: 1000
access-log: /dev/null # enable logging
EOT
my $conn = IO::Socket::INET->new(
PeerHost => '127.0.0.1',
PeerPort => $server->{port},
Proto => 'tcp',
) or die "failed to connect to 127.0.0.1:$server->{port}:$!";
doit($conn);
};
done_testing;
|