Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Re: PSGI, Plack

by Corion (Pope)
on Oct 24, 2012 at 11:29 UTC ( #1000609=note: print w/replies, xml ) Need Help??

in reply to PSGI, Plack

I have written a toy "enforce-https" middleware, and also a toy "run two servers" middleware, but not yet released onto CPAN.

To write a multiplexing server that can serve PSGI applications from two (or more) ports, you will have to look at the various backends. I chose AnyEvent, which is based on the idea of nonblocking handling. The existing implementations on CPAN (partially in Server::Starter I think) didn't work on Windows for me. One ugly part is that SSL does not work well on Windows+Strawberry+AnyEvent, I think because OpenSSL is linked to a different memory allocator than Strawberry Perl.

I think SSL-enabling a server is basically only the process of "replacing" the socket the server reads from by a socket that knows SSL. AnyEvent did that nicely, but I don't know what other servers/frameworks do.

Update: Plack::Handler::AnyEvent::HTTPD needs a small patch to allow SSL:

Replies are listed 'Best First'.
Re^2: PSGI, Plack
by Corion (Pope) on Oct 24, 2012 at 18:06 UTC

    I found that multi-server implementation. It does not only use AnyEvent, it also relies on Coro to make switching between server loops easy when they get blocked. The code was developed under Windows, but the SSL problems alluded to above still apply.

    #!perl -w use strict; use Coro; use AnyEvent; use AnyEvent::TLS; use Plack::Handler::AnyEvent::HTTPD; use Dancer (); use App::Regexplain; use Data::Dumper; my %config = ( 'http' => { host => '', port => 8080, protocol => 'http', + proto => 'tcp' }, 'https' => { host => '', port => 8443, ssl => { cert_file => 'C:/Projekte/App-Regexplain/certs/testcert.pem', key_file => 'C:/Projekte/App-Regexplain/certs/testkey-nopass.p +em', }, }, ); =begin other_api __PACKAGE__->run( port => [8080, "8443/ssl"], ipv => '*', # IPv6 if available SSL_key_file => '/my/key', SSL_cert_file => '/my/cert', ); =cut for my $serverkey (sort keys %config) { my $config = $config{ $serverkey }; my $runner = Plack::Runner::Multi->new; $runner->parse_options( '--server', 'AnyEvent::HTTPD', '-p', $config->{port}, '-o', $config->{host}, 'bin\\', ); if( $config->{ssl} ) { #$config->{ ssl } = AnyEvent::TLS->new( # %{$config->{ ssl }} #); push @{$runner->{options}}, ssl => $config->{ssl} }; my ($loader,$server,$app) = $runner->psgi_app(); async { $loader->preload_app($app); $loader->run($server); }; }; # Kick off the event loop AnyEvent->condvar->recv; package Plack::Runner::Multi; use strict; use parent 'Plack::Runner'; use Coro; use Data::Dumper; # Paste from Plack::Runner::run except the $loader->run at the end sub psgi_app { my $self = shift; #unless (ref $self) { # $self = $self->new; # $self->parse_options(@_); # return $self->run; #} unless ($self->{options}) { $self->parse_options(@_); }; my @args = @{$self->{argv}}; $self->setup; my $app = $self->locate_app(@args); $ENV{PLACK_ENV} ||= $self->{env} || 'development'; if ($ENV{PLACK_ENV} eq 'development') { $app = $self->prepare_devel($app); } if ($self->{access_log}) { open my $logfh, ">>", $self->{access_log} or die "open($self->{access_log}): $!"; $logfh->autoflush(1); $app = $self->apply_middleware($app, 'AccessLog', logger => su +b { $logfh->print( @_ ) }); } my $loader = $self->loader; #warn "Loading Server with " . Dumper $self->{options}; my $server = $self->load_server($loader); #$loader->preload_app($app); return ($loader, $server, $app); #$loader->run($server); } 1;

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1000609]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2017-11-24 21:20 GMT
Find Nodes?
    Voting Booth?
    In order to be able to say "I know Perl", you must have:

    Results (353 votes). Check out past polls.