Skip to content

Commit

Permalink
add ALPN support
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Mar 1, 2016
1 parent 6b978f9 commit a7602f7
Show file tree
Hide file tree
Showing 12 changed files with 69 additions and 14 deletions.
2 changes: 1 addition & 1 deletion lib/Mojo/IOLoop.pm
Expand Up @@ -300,7 +300,7 @@ loaded.
For better scalability (epoll, kqueue) and to provide non-blocking name
resolution, SOCKS5 as well as TLS support, the optional modules L<EV> (4.0+),
L<Net::DNS::Native> (0.15+), L<IO::Socket::Socks> (0.64+) and
L<IO::Socket::SSL> (1.94+) will be used automatically if possible. Individual
L<IO::Socket::SSL> (2.009+) will be used automatically if possible. Individual
features can also be disabled with the C<MOJO_NO_NDN>, C<MOJO_NO_SOCKS> and
C<MOJO_NO_TLS> environment variables.
Expand Down
14 changes: 11 additions & 3 deletions lib/Mojo/IOLoop/Client.pm
Expand Up @@ -16,7 +16,7 @@ my $NDN = NDN ? Net::DNS::Native->new(pool => 5, extra_thread => 1) : undef;
# TLS support requires IO::Socket::SSL
use constant TLS => $ENV{MOJO_NO_TLS}
? 0
: eval 'use IO::Socket::SSL 1.94 (); 1';
: eval 'use IO::Socket::SSL 2.009 (); 1';
use constant TLS_READ => TLS ? IO::Socket::SSL::SSL_WANT_READ() : 0;
use constant TLS_WRITE => TLS ? IO::Socket::SSL::SSL_WANT_WRITE() : 0;

Expand Down Expand Up @@ -163,7 +163,7 @@ sub _try_tls {

my $handle = $self->{handle};
return $self->_cleanup->emit(connect => $handle) unless $args->{tls};
return $self->emit(error => 'IO::Socket::SSL 1.94+ required for TLS support')
return $self->emit(error => 'IO::Socket::SSL 2.009+ required for TLS support')
unless TLS;

# Upgrade
Expand All @@ -180,6 +180,8 @@ sub _try_tls {
SSL_verifycn_name => $args->{address},
SSL_verifycn_scheme => $args->{tls_ca} ? 'http' : undef
);
$options{SSL_alpn_protocols} = $args->{tls_protocols}
if IO::Socket::SSL->can_alpn;
my $reactor = $self->reactor;
$reactor->remove($handle);
return $self->emit(error => 'TLS upgrade failed')
Expand Down Expand Up @@ -271,7 +273,7 @@ implements the following new ones.
Open a socket connection to a remote host. Note that non-blocking name
resolution depends on L<Net::DNS::Native> (0.15+), SOCKS5 support on
L<IO::Socket::Socks> (0.64), and TLS support on L<IO::Socket::SSL> (1.94+).
L<IO::Socket::Socks> (0.64), and TLS support on L<IO::Socket::SSL> (2.009+).
These options are currently available:
Expand Down Expand Up @@ -356,6 +358,12 @@ Path to the TLS certificate file.
Path to the TLS key file.
=item tls_protocols
tls_protocols => ['foo', 'bar']
ALPN protocols to negotiate.
=back
=head1 SEE ALSO
Expand Down
14 changes: 11 additions & 3 deletions lib/Mojo/IOLoop/Server.pm
Expand Up @@ -12,7 +12,7 @@ use Socket qw(IPPROTO_TCP TCP_NODELAY);
# TLS support requires IO::Socket::SSL
use constant TLS => $ENV{MOJO_NO_TLS}
? 0
: eval 'use IO::Socket::SSL 1.94 (); 1';
: eval 'use IO::Socket::SSL 2.009 (); 1';
use constant TLS_READ => TLS ? IO::Socket::SSL::SSL_WANT_READ() : 0;
use constant TLS_WRITE => TLS ? IO::Socket::SSL::SSL_WANT_WRITE() : 0;

Expand Down Expand Up @@ -79,7 +79,7 @@ sub listen {
$self->{handle} = $handle;

return unless $args->{tls};
croak "IO::Socket::SSL 1.94+ required for TLS support" unless TLS;
croak "IO::Socket::SSL 2.009+ required for TLS support" unless TLS;

weaken $self;
my $tls = $self->{tls} = {
Expand All @@ -94,6 +94,8 @@ sub listen {
SSL_startHandshake => 0,
SSL_verify_mode => $args->{tls_verify} // ($args->{tls_ca} ? 0x03 : 0x00)
};
$tls->{SSL_alpn_protocols} = $args->{tls_protocols}
if IO::Socket::SSL->can_alpn;
$tls->{SSL_ca_file} = $args->{tls_ca}
if $args->{tls_ca} && -T $args->{tls_ca};
$tls->{SSL_cipher_list} = $args->{tls_ciphers} if $args->{tls_ciphers};
Expand Down Expand Up @@ -235,7 +237,7 @@ Get handle for server.
$server->listen(port => 3000);
Create a new listen socket. Note that TLS support depends on L<IO::Socket::SSL>
(1.94+).
(2.009+).
These options are currently available:
Expand Down Expand Up @@ -299,6 +301,12 @@ L<https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-STRINGS>.
Path to the TLS key file, defaults to a built-in test key.
=item tls_protocols
tls_protocols => ['foo', 'bar']
ALPN protocols to negotiate.
=item tls_verify
tls_verify => 0x00
Expand Down
11 changes: 11 additions & 0 deletions lib/Mojo/IOLoop/Stream.pm
Expand Up @@ -36,6 +36,11 @@ sub is_writing {

sub new { shift->SUPER::new(handle => shift, buffer => '', timeout => 15) }

sub protocol {
return undef unless my $handle = shift->{handle};
return $handle->can('alpn_selected') ? $handle->alpn_selected : undef;
}

sub start {
my $self = shift;

Expand Down Expand Up @@ -272,6 +277,12 @@ Check if stream is writing.
Construct a new L<Mojo::IOLoop::Stream> object.
=head2 protocol
my $proto = $stream->protocol;
Selected ALPN protocol.
=head2 start
$stream->start;
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojo/Server/Daemon.pm
Expand Up @@ -273,7 +273,7 @@ and multiple event loop support.
For better scalability (epoll, kqueue) and to provide non-blocking name
resolution, SOCKS5 as well as TLS support, the optional modules L<EV> (4.0+),
L<Net::DNS::Native> (0.15+), L<IO::Socket::Socks> (0.64+) and
L<IO::Socket::SSL> (1.94+) will be used automatically if possible. Individual
L<IO::Socket::SSL> (2.009+) will be used automatically if possible. Individual
features can also be disabled with the C<MOJO_NO_NDN>, C<MOJO_NO_SOCKS> and
C<MOJO_NO_TLS> environment variables.
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojo/Server/Hypnotoad.pm
Expand Up @@ -175,7 +175,7 @@ file with it, and send a L</"USR2"> signal to the already running server.
For better scalability (epoll, kqueue) and to provide non-blocking name
resolution, SOCKS5 as well as TLS support, the optional modules L<EV> (4.0+),
L<Net::DNS::Native> (0.15+), L<IO::Socket::Socks> (0.64+) and
L<IO::Socket::SSL> (1.94+) will be used automatically if possible. Individual
L<IO::Socket::SSL> (2.009+) will be used automatically if possible. Individual
features can also be disabled with the C<MOJO_NO_NDN>, C<MOJO_NO_SOCKS> and
C<MOJO_NO_TLS> environment variables.
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojo/Server/Morbo.pm
Expand Up @@ -112,7 +112,7 @@ To start applications with it you can use the L<morbo> script.
For better scalability (epoll, kqueue) and to provide non-blocking name
resolution, SOCKS5 as well as TLS support, the optional modules L<EV> (4.0+),
L<Net::DNS::Native> (0.15+), L<IO::Socket::Socks> (0.64+) and
L<IO::Socket::SSL> (1.94+) will be used automatically if possible. Individual
L<IO::Socket::SSL> (2.009+) will be used automatically if possible. Individual
features can also be disabled with the C<MOJO_NO_NDN>, C<MOJO_NO_SOCKS> and
C<MOJO_NO_TLS> environment variables.
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojo/UserAgent.pm
Expand Up @@ -426,7 +426,7 @@ safely.
For better scalability (epoll, kqueue) and to provide non-blocking name
resolution, SOCKS5 as well as TLS support, the optional modules L<EV> (4.0+),
L<Net::DNS::Native> (0.15+), L<IO::Socket::Socks> (0.64+) and
L<IO::Socket::SSL> (1.94+) will be used automatically if possible. Individual
L<IO::Socket::SSL> (2.009+) will be used automatically if possible. Individual
features can also be disabled with the C<MOJO_NO_NDN>, C<MOJO_NO_SOCKS> and
C<MOJO_NO_TLS> environment variables.
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojolicious/Command/version.pm
Expand Up @@ -24,7 +24,7 @@ CORE
OPTIONAL
EV 4.0+ ($ev)
IO::Socket::Socks 0.64+ ($socks)
IO::Socket::SSL 1.94+ ($tls)
IO::Socket::SSL 2.009+ ($tls)
Net::DNS::Native 0.15+ ($ndn)
EOF
Expand Down
2 changes: 1 addition & 1 deletion t/mojo/daemon_ipv6_tls.t
Expand Up @@ -9,7 +9,7 @@ plan skip_all => 'set TEST_IPV6 to enable this test (developer only!)'
unless $ENV{TEST_IPV6};
plan skip_all => 'set TEST_TLS to enable this test (developer only!)'
unless $ENV{TEST_TLS};
plan skip_all => 'IO::Socket::SSL 1.94+ required for this test!'
plan skip_all => 'IO::Socket::SSL 2.009+ required for this test!'
unless Mojo::IOLoop::Server::TLS;

# To regenerate all required certificates run these commands (07.01.2016)
Expand Down
28 changes: 28 additions & 0 deletions t/mojo/ioloop_tls.t
Expand Up @@ -359,4 +359,32 @@ is $server, 'accepted', 'right result';
is $client, 'connected', 'right result';
ok !$client_err, 'no error';

# ALPN
SKIP: {
skip 'ALPN support required!', 1 unless IO::Socket::SSL->can_alpn;

my ($server_proto, $client_proto);
$id = Mojo::IOLoop->server(
address => '127.0.0.1',
tls => 1,
tls_protocols => ['foo', 'bar', 'baz'],
sub {
my ($loop, $stream) = @_;
$server_proto = $stream->protocol;
$stream->close;
}
);
$port = Mojo::IOLoop->acceptor($id)->port;
Mojo::IOLoop->client(
{port => $port, tls => 1, tls_protocols => ['baz', 'bar']} => sub {
my ($loop, $err, $stream) = @_;
$client_proto = $stream->protocol;
$stream->on(close => sub { Mojo::IOLoop->stop });
}
);
Mojo::IOLoop->start;
is $server_proto, 'baz', 'right protocol';
is $client_proto, 'baz', 'right protocol';
}

done_testing();
2 changes: 1 addition & 1 deletion t/mojo/user_agent_online.t
Expand Up @@ -10,7 +10,7 @@ use Mojo::IOLoop::Server;

plan skip_all => 'set TEST_ONLINE to enable this test (developer only!)'
unless $ENV{TEST_ONLINE};
plan skip_all => 'IO::Socket::SSL 1.94+ required for this test!'
plan skip_all => 'IO::Socket::SSL 2.009+ required for this test!'
unless Mojo::IOLoop::Server::TLS;

use IO::Socket::INET;
Expand Down

0 comments on commit a7602f7

Please sign in to comment.