Skip to content

Commit b9337d8

Browse files
committed
Tests: simplified HTTP/2 SSL tests with IO::Socket::SSL.
Tests are converted to use Test::Nginx infrastructure, similar to dcfe53a. Further, expect ALPN to be negotiated with supporting OpenSSL versions. Previously, such tests might be silently skipped on failure.
1 parent bb9d02b commit b9337d8

5 files changed

+52
-139
lines changed

h2_ssl.t

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ select STDOUT; $| = 1;
2828
my $t = Test::Nginx->new()->has(qw/http http_ssl http_v2 socket_ssl_alpn/)
2929
->has_daemon('openssl');
3030

31+
plan(skip_all => 'no ALPN support in OpenSSL')
32+
if $t->has_module('OpenSSL') and not $t->has_feature('openssl:1.0.2');
33+
3134
$t->write_file_expand('nginx.conf', <<'EOF');
3235
3336
%%TEST_GLOBALS%%
@@ -41,7 +44,7 @@ http {
4144
%%TEST_GLOBALS_HTTP%%
4245
4346
server {
44-
listen 127.0.0.1:8080 http2 ssl;
47+
listen 127.0.0.1:8443 http2 ssl;
4548
server_name localhost;
4649
4750
ssl_certificate_key localhost.key;
@@ -81,7 +84,6 @@ open OLDERR, ">&", \*STDERR; close STDERR;
8184
$t->run();
8285
open STDERR, ">&", \*OLDERR;
8386

84-
plan(skip_all => 'no ALPN negotiation') unless defined getconn();
8587
$t->plan(4);
8688

8789
###############################################################################
@@ -110,7 +112,8 @@ is($frame->{headers}->{':status'}, 200, 'alpn to HTTP/2');
110112
# h2c preface on ssl-enabled socket is rejected as invalid HTTP/1.x request,
111113
# ensure that HTTP/2 auto-detection doesn't kick in
112114

113-
like(http("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"), qr/Bad Request/,
115+
like(http("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n",
116+
PeerAddr => '127.0.0.1:' . port(8443)), qr/Bad Request/,
114117
'no h2c on ssl socket');
115118

116119
# client cancels last stream after HEADERS has been created,
@@ -135,39 +138,13 @@ $t->stop();
135138

136139
sub getconn {
137140
my ($alpn) = @_;
138-
$alpn = ['h2'] if !defined $alpn;
139-
140141
my $sock = get_ssl_socket($alpn);
141-
my $s = Test::Nginx::HTTP2->new(undef, socket => $sock)
142-
if $sock->alpn_selected();
142+
Test::Nginx::HTTP2->new(undef, socket => $sock);
143143
}
144144

145145
sub get_ssl_socket {
146146
my ($alpn) = @_;
147-
my $s;
148-
149-
eval {
150-
local $SIG{ALRM} = sub { die "timeout\n" };
151-
local $SIG{PIPE} = sub { die "sigpipe\n" };
152-
alarm(8);
153-
$s = IO::Socket::SSL->new(
154-
Proto => 'tcp',
155-
PeerAddr => '127.0.0.1',
156-
PeerPort => port(8080),
157-
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE(),
158-
SSL_alpn_protocols => $alpn,
159-
SSL_error_trap => sub { die $_[1] }
160-
);
161-
alarm(0);
162-
};
163-
alarm(0);
164-
165-
if ($@) {
166-
log_in("died: $@");
167-
return undef;
168-
}
169-
170-
return $s;
147+
return http('', start => 1, SSL => 1, SSL_alpn_protocols => $alpn);
171148
}
172149

173150
###############################################################################

h2_ssl_proxy_cache.t

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ select STDERR; $| = 1;
2424
select STDOUT; $| = 1;
2525

2626
my $t = Test::Nginx->new()
27-
->has(qw/http http_ssl http_v2 proxy cache socket_ssl/)
27+
->has(qw/http http_ssl http_v2 proxy cache socket_ssl_alpn/)
2828
->has_daemon('openssl');
2929

30+
plan(skip_all => 'no ALPN support in OpenSSL')
31+
if $t->has_module('OpenSSL') and not $t->has_feature('openssl:1.0.2');
32+
3033
$t->write_file_expand('nginx.conf', <<'EOF');
3134
3235
%%TEST_GLOBALS%%
@@ -42,7 +45,7 @@ http {
4245
proxy_cache_path %%TESTDIR%%/cache keys_zone=NAME:1m;
4346
4447
server {
45-
listen 127.0.0.1:8080 http2 ssl sndbuf=32k;
48+
listen 127.0.0.1:8443 http2 ssl sndbuf=32k;
4649
server_name localhost;
4750
4851
ssl_certificate_key localhost.key;
@@ -92,22 +95,21 @@ open OLDERR, ">&", \*STDERR; close STDERR;
9295
$t->run();
9396
open STDERR, ">&", \*OLDERR;
9497

95-
plan(skip_all => 'no ALPN negotiation') unless defined getconn(port(8080));
9698
$t->plan(1);
9799

98100
###############################################################################
99101

100102
# client cancels stream with a cacheable request sent to upstream causing alert
101103

102-
my $s = getconn(port(8080));
104+
my $s = getconn();
103105
ok($s, 'ssl connection');
104106

105107
my $sid = $s->new_stream();
106108
$s->h2_rst($sid, 8);
107109

108110
# large response may stuck in SSL buffer and won't be sent producing alert
109111

110-
my $s2 = getconn(port(8080));
112+
my $s2 = getconn();
111113
$sid = $s2->new_stream({ path => '/tbig.html' });
112114
$s2->h2_window(2**30, $sid);
113115
$s2->h2_window(2**30);
@@ -119,17 +121,8 @@ $t->stop();
119121
###############################################################################
120122

121123
sub getconn {
122-
my ($port) = @_;
123-
my $s;
124-
125-
eval {
126-
my $sock = Test::Nginx::HTTP2::new_socket($port, SSL => 1,
127-
alpn => 'h2');
128-
$s = Test::Nginx::HTTP2->new($port, socket => $sock)
129-
if $sock->alpn_selected();
130-
};
131-
132-
return $s;
124+
my $sock = http('', start => 1, SSL => 1, SSL_alpn_protocols => ['h2']);
125+
Test::Nginx::HTTP2->new(undef, socket => $sock);
133126
}
134127

135128
###############################################################################

h2_ssl_proxy_protocol.t

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ my $sock = http($proxy, start => 1);
9090
http('', start => 1, socket => $sock, SSL => 1, SSL_alpn_protocols => ['h2']);
9191

9292
SKIP: {
93-
skip 'no ALPN negotiation', 2 unless $sock->alpn_selected();
93+
skip 'no ALPN support in OpenSSL', 2
94+
if $t->has_module('OpenSSL') and not $t->has_feature('openssl:1.0.2');
9495

9596
my $s = Test::Nginx::HTTP2->new(undef, socket => $sock);
9697
my $sid = $s->new_stream({ path => '/pp' });

h2_ssl_variables.t

Lines changed: 22 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ use Test::Nginx::HTTP2;
2323
select STDERR; $| = 1;
2424
select STDOUT; $| = 1;
2525

26-
my $t = Test::Nginx->new()->has(qw/http http_ssl http_v2 rewrite socket_ssl/)
27-
->has_daemon('openssl')->plan(4);
26+
my $t = Test::Nginx->new()
27+
->has(qw/http http_ssl http_v2 rewrite socket_ssl_alpn/)
28+
->has_daemon('openssl');
29+
30+
plan(skip_all => 'no ALPN support in OpenSSL')
31+
if $t->has_module('OpenSSL') and not $t->has_feature('openssl:1.0.2');
2832

2933
$t->write_file_expand('nginx.conf', <<'EOF');
3034
@@ -39,7 +43,7 @@ http {
3943
%%TEST_GLOBALS_HTTP%%
4044
4145
server {
42-
listen 127.0.0.1:8080 http2 ssl;
46+
listen 127.0.0.1:8443 http2 ssl;
4347
server_name localhost;
4448
4549
ssl_certificate_key localhost.key;
@@ -84,69 +88,27 @@ open OLDERR, ">&", \*STDERR; close STDERR;
8488
$t->run();
8589
open STDERR, ">&", \*OLDERR;
8690

87-
###############################################################################
88-
89-
my ($s, $sid, $frames, $frame);
90-
91-
my $has_npn = eval { Test::Nginx::HTTP2::new_socket(port(8080), SSL => 1,
92-
npn => 'h2')->next_proto_negotiated() };
93-
my $has_alpn = eval { Test::Nginx::HTTP2::new_socket(port(8080), SSL => 1,
94-
alpn => 'h2')->alpn_selected() };
95-
96-
# SSL/TLS connection, ALPN
97-
98-
SKIP: {
99-
skip 'OpenSSL ALPN support required', 1 unless $has_alpn;
100-
101-
$s = Test::Nginx::HTTP2->new(port(8080), SSL => 1, alpn => 'h2');
102-
$sid = $s->new_stream({ path => '/h2' });
103-
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
104-
105-
($frame) = grep { $_->{type} eq "DATA" } @$frames;
106-
is($frame->{data}, 'h2', 'http variable - alpn');
107-
108-
}
109-
110-
# $server_protocol - SSL/TLS connection, ALPN
111-
112-
SKIP: {
113-
skip 'OpenSSL ALPN support required', 1 unless $has_alpn;
91+
$t->plan(4);
11492

115-
$s = Test::Nginx::HTTP2->new(port(8080), SSL => 1, alpn => 'h2');
116-
$sid = $s->new_stream({ path => '/sp' });
117-
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
118-
119-
($frame) = grep { $_->{type} eq "DATA" } @$frames;
120-
is($frame->{data}, 'HTTP/2.0', 'server_protocol variable - alpn');
121-
122-
}
123-
124-
# $scheme - SSL/TLS connection, ALPN
125-
126-
SKIP: {
127-
skip 'OpenSSL ALPN support required', 1 unless $has_alpn;
128-
129-
$s = Test::Nginx::HTTP2->new(port(8080), SSL => 1, alpn => 'h2');
130-
$sid = $s->new_stream({ path => '/scheme' });
131-
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
132-
133-
($frame) = grep { $_->{type} eq "DATA" } @$frames;
134-
is($frame->{data}, 'https', 'scheme variable - alpn');
135-
136-
}
93+
###############################################################################
13794

138-
# $https - SSL/TLS connection, ALPN
95+
is(get('/h2'), 'h2', 'http2 variable');
96+
is(get('/sp'), 'HTTP/2.0', 'server_protocol variable');
97+
is(get('/scheme'), 'https', 'scheme variable');
98+
is(get('/https'), 'on', 'https variable');
13999

140-
SKIP: {
141-
skip 'OpenSSL ALPN support required', 1 unless $has_alpn;
100+
###############################################################################
142101

143-
$s = Test::Nginx::HTTP2->new(port(8080), SSL => 1, alpn => 'h2');
144-
$sid = $s->new_stream({ path => '/https' });
145-
$frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
102+
sub get {
103+
my ($uri) = @_;
146104

147-
($frame) = grep { $_->{type} eq "DATA" } @$frames;
148-
is($frame->{data}, 'on', 'https variable - alpn');
105+
my $sock = http('', start => 1, SSL => 1, SSL_alpn_protocols => ['h2']);
106+
my $s = Test::Nginx::HTTP2->new(undef, socket => $sock);
107+
my $sid = $s->new_stream({ path => $uri });
108+
my $frames = $s->read(all => [{ sid => $sid, fin => 1 }]);
149109

110+
my ($frame) = grep { $_->{type} eq "DATA" } @$frames;
111+
return $frame->{data};
150112
}
151113

152114
###############################################################################

h2_ssl_verify_client.t

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ select STDOUT; $| = 1;
2626
my $t = Test::Nginx->new()->has(qw/http http_ssl sni http_v2 socket_ssl_alpn/)
2727
->has_daemon('openssl');
2828

29+
plan(skip_all => 'no ALPN support in OpenSSL')
30+
if $t->has_module('OpenSSL') and not $t->has_feature('openssl:1.0.2');
31+
2932
$t->write_file_expand('nginx.conf', <<'EOF');
3033
3134
%%TEST_GLOBALS%%
@@ -46,7 +49,7 @@ http {
4649
add_header X-Verify $ssl_client_verify;
4750
4851
server {
49-
listen 127.0.0.1:8080 ssl http2;
52+
listen 127.0.0.1:8443 ssl http2;
5053
server_name localhost;
5154
5255
ssl_client_certificate client.crt;
@@ -55,7 +58,7 @@ http {
5558
}
5659
5760
server {
58-
listen 127.0.0.1:8080 ssl http2;
61+
listen 127.0.0.1:8443 ssl http2;
5962
server_name example.com;
6063
6164
location / { }
@@ -88,8 +91,6 @@ open OLDERR, ">&", \*STDERR; close STDERR;
8891
$t->run();
8992
open STDERR, ">&", \*OLDERR;
9093

91-
my $s = get_ssl_socket();
92-
plan(skip_all => 'no alpn') unless $s->alpn_selected();
9394
$t->plan(3);
9495

9596
###############################################################################
@@ -102,33 +103,12 @@ is(get('localhost', 'example.com')->{':status'}, '421', 'misdirected');
102103

103104
sub get_ssl_socket {
104105
my ($sni) = @_;
105-
my $s;
106-
107-
eval {
108-
local $SIG{ALRM} = sub { die "timeout\n" };
109-
local $SIG{PIPE} = sub { die "sigpipe\n" };
110-
alarm(8);
111-
$s = IO::Socket::SSL->new(
112-
Proto => 'tcp',
113-
PeerAddr => '127.0.0.1',
114-
PeerPort => port(8080),
115-
SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE(),
116-
SSL_alpn_protocols => [ 'h2' ],
117-
SSL_hostname => $sni,
118-
SSL_cert_file => "$d/client.crt",
119-
SSL_key_file => "$d/client.key",
120-
SSL_error_trap => sub { die $_[1] }
121-
);
122-
alarm(0);
123-
};
124-
alarm(0);
125-
126-
if ($@) {
127-
log_in("died: $@");
128-
return undef;
129-
}
130-
131-
return $s;
106+
http('', start => 1,
107+
SSL => 1,
108+
SSL_alpn_protocols => [ 'h2' ],
109+
SSL_hostname => $sni,
110+
SSL_cert_file => "$d/client.crt",
111+
SSL_key_file => "$d/client.key");
132112
}
133113

134114
sub get {

0 commit comments

Comments
 (0)