Skip Menu |

This queue is for tickets about the Net-Async-HTTP-Server CPAN distribution.

Report information
The Basics
Id: 86436
Status: resolved
Priority: 0/
Queue: Net-Async-HTTP-Server

People
Owner: Nobody in particular
Requestors: ARISTOTLE [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: 0.06



Subject: Support HTTPS via command line switch in Plack handler
There should to instruct the Plack handler to set up an SSL-based port, from the command line. In particular, it should be possible to have both a plain port and an SSL-based port.
On Wed Jun 26 09:08:20 2013, ARISTOTLE wrote: Show quoted text
> There should to instruct the Plack handler to set up an SSL-based > port, from the command line. > > In particular, it should be possible to have both a plain port and an > SSL-based port.
Done. -- Paul Evans
Subject: rt86436.patch
=== modified file 'lib/Plack/Handler/Net/Async/HTTP/Server.pm' --- lib/Plack/Handler/Net/Async/HTTP/Server.pm 2013-12-30 02:43:38 +0000 +++ lib/Plack/Handler/Net/Async/HTTP/Server.pm 2014-03-26 18:13:00 +0000 @@ -39,6 +39,14 @@ This is internally implemented using L<Net::Async::HTTP::Server::PSGI>; further information on environment etc.. is documented there. +If L<IO::Async::SSL> is available, this handler supports accepting connections +via C<https> + + plackup -s Net::Async::HTTP::Server --ssl ... + +Any other options whose names start C<ssl_> will be passed on to the SSL +listen method. + =cut =head1 METHODS @@ -94,6 +102,10 @@ map { $_ => delete $opts{$_} } qw( listen server_ready socket queuesize ), }, $class; + # Grab all of the SSL options + $self->{ssl} = 1 if exists $opts{ssl}; delete $opts{ssl}; + $self->{$_} = delete $opts{$_} for grep m/^ssl_/, keys %opts; + keys %opts and die "Unrecognised keys " . join( ", ", sort keys %opts ); return $self; @@ -138,27 +150,39 @@ else { my ( $host, $service ) = $listen =~ m/^(.*):(.*?)$/; + my %SSL_args; + if( $self->{ssl} ) { + require IO::Async::SSL; + %SSL_args = ( + extensions => [qw( SSL )], + ); + + foreach my $key ( grep m/^ssl_/, keys %$self ) { + my $val = $self->{$key}; + # IO::Async::Listener extension wants uppercase "SSL" + $key =~ s/^ssl/SSL/; + + $SSL_args{$key} = $val; + }; + } + $httpserver->listen( host => $host, service => $service, socktype => "stream", queuesize => $queuesize, + %SSL_args, + on_notifier => sub { $self->{server_ready}->( { host => $host, port => $service, + proto => $self->{ssl} ? "https" : "http", server_software => ref $self, } ) if $self->{server_ready}; }, - - on_resolve_error => sub { - die "Cannot resolve - $_[-1]\n"; - }, - on_listen_error => sub { - die "Cannot listen - $_[-1]\n"; - }, - ); + )->get; } }
Released in 0.06 -- Paul Evans
On Wed Mar 26 14:13:29 2014, PEVANS wrote: Show quoted text
> Done.
Thanks. But… the code does not look like it’s possible to run a server that listens on both a plain non-SSL port and an SSL port at the same time. Or am I misreading the patch (in which case please re-close)? E.g. Starman allows :SSL as a third component for a listen port spec, so you can say --listen :5000 --listen :5443:SSL and get it listening on both ports but only doing SSL on 5443.
On Thu Mar 27 07:11:42 2014, ARISTOTLE wrote: Show quoted text
> On Wed Mar 26 14:13:29 2014, PEVANS wrote:
> > Done.
> > Thanks. But… the code does not look like it’s possible to run a server > that listens on both a plain non-SSL port and an SSL port at the same > time. Or am I misreading the patch (in which case please re-close)? > > E.g. Starman allows :SSL as a third component for a listen port spec, > so you can say --listen :5000 --listen :5443:SSL and get it listening > on both ports but only doing SSL on 5443.
Unfortunately this doesn't look possible with plackup. https://metacpan.org/pod/distribution/Plack/script/plackup If I run $ plackup -Ilib -s Net::Async::HTTP::Server psgifiles/helloworld.psgi --listen ":5000:SSL" Then plackup's special processing here will fail to parse this listen argument as a socket hostname:port request, so falls back on it being a UNIX socket path. I think the logic is around here somewhere: https://metacpan.org/source/MIYAGAWA/Plack-1.0030/lib/Plack/Runner.pm#L93 Long story short though - this doesn't appear to be easily doable. :( -- Paul Evans
On Fri Mar 28 11:20:31 2014, PEVANS wrote: Show quoted text
> Unfortunately this doesn't look possible with plackup.
Actually on further inspection it is possible, but only by ignoring plackup's own parsing of the --listen arguments and doing it again myself. Find attached a new patch. This allows: $ plackup -Ilib -s Net::Async::HTTP::Server psgifiles/helloworld.psgi --listen "[::1]:5000" --listen ":5443:SSL" Plack::Handler::Net::Async::HTTP::Server: Accepting connections at http://::1:5000/ Plack::Handler::Net::Async::HTTP::Server: Accepting connections at https://0:5443/ -- Paul Evans
Subject: rt86436-2.patch
=== modified file 'lib/Plack/Handler/Net/Async/HTTP/Server.pm' --- lib/Plack/Handler/Net/Async/HTTP/Server.pm 2014-03-26 18:29:01 +0000 +++ lib/Plack/Handler/Net/Async/HTTP/Server.pm 2014-03-28 15:38:19 +0000 @@ -44,6 +44,10 @@ plackup -s Net::Async::HTTP::Server --ssl ... +Or per-listen argument by appending C<:SSL>, as + + plackup -s Net::Async::HTTP::Server --listen ":8443:SSL" ... + Any other options whose names start C<ssl_> will be passed on to the SSL listen method. @@ -97,9 +101,10 @@ delete $opts{host}; delete $opts{port}; + delete $opts{socket}; my $self = bless { - map { $_ => delete $opts{$_} } qw( listen server_ready socket queuesize ), + map { $_ => delete $opts{$_} } qw( listen server_ready queuesize ), }, $class; # Grab all of the SSL options @@ -133,9 +138,24 @@ $loop->add( $httpserver ); - if( $self->{socket} ) { - my $path = $self->{socket}; - + # IPv6 addresses contain colons. They'll be wrapped in [] brackets + my $host; + my $path; + + if( $listen =~ s/^\[([0-9a-f:]+)\]://i ) { + $host = $1; + } + elsif( $listen =~ s/^([^:]+?):// ) { + $host = $1; + } + elsif( $listen =~ s/^:// ) { + # OK + } + else { + $path = $listen; + } + + if( defined $path ) { require IO::Socket::UNIX; unlink $path if -e $path; @@ -148,10 +168,11 @@ $httpserver->configure( handle => $socket ); } else { - my ( $host, $service ) = $listen =~ m/^(.*):(.*?)$/; + my ( $service, $ssl ) = split m/:/, $listen; + $ssl ||= $self->{ssl}; my %SSL_args; - if( $self->{ssl} ) { + if( $ssl ) { require IO::Async::SSL; %SSL_args = ( extensions => [qw( SSL )], @@ -178,7 +199,7 @@ $self->{server_ready}->( { host => $host, port => $service, - proto => $self->{ssl} ? "https" : "http", + proto => $ssl ? "https" : "http", server_software => ref $self, } ) if $self->{server_ready}; },
On Fri Mar 28 11:40:10 2014, PEVANS wrote: Show quoted text
> Find attached a new patch. This allows: > > $ plackup -Ilib -s Net::Async::HTTP::Server psgifiles/helloworld.psgi > --listen "[::1]:5000" --listen ":5443:SSL" > Plack::Handler::Net::Async::HTTP::Server: Accepting connections at > http://::1:5000/ > Plack::Handler::Net::Async::HTTP::Server: Accepting connections at > https://0:5443/
Beautiful. Thank you. :-)