Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

SSL with HTTP::Server::Simple and Net::Server

by Tanktalus (Canon)
on Apr 26, 2011 at 21:19 UTC ( [id://901426]=perlquestion: print w/replies, xml ) Need Help??

Tanktalus has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to create a simple server to transfer groups of large files - tye suggested pointed me in a direction where I found HTTP::Server::Simple as I could use the HTTP protocol to send multi-part data that would include both metadata and multiple files, just as a browser does. Since HTTP::Server::Simple supports Net::Server, I threw that in, because the files being sent are large (multiple GB) and it's perfectly reasonable that more than one upload will go on at a time, so Net::Server::PreFork seemed like a simple way to do this.

All this is working fine. As long as I use "http://" on the client. However, since there will be user IDs and passwords sent in the metadata, I really want to use SSL. The client side, using LWP, is simple enough - change http: to https:, and we're good. However, the server side is much more convoluted. Here is a boiled-down example:

use strict; use warnings; my $s = Server->new(@ARGV); $s->background( SSL_cert_file => '/etc/ssl/apache2/server.crt', SSL_key_file => '/etc/ssl/apache2/server.key', ); exit; package Server; use base 'HTTP::Server::Simple::CGI'; sub net_server { 'Net::Server::PreFork' }
If I run this with the param of "12345", all is good. I can point my browser at "http://localhost:12345" and get the default HTTP::Server::Simple::CGI page. However, if I kill that, then run it again with a parameter of "12345/ssleay", then I get:
2011/04/26-15:03:18 Server::NetServer0 (type Net::Server::PreFork) sta +rting! pid(6116) Using default listen value of 128 Binding to SSLEAY port 12345 on host * SSLeay missing SSL_key_file.
And the process is not running in the background - it died. I've run this through the debugger a few times, without quite figuring out how these parameters are supposed to be passed in, nor why they are missing from $s->{server} where Net::Server::Proto::SSLEAY is expecting them.

I must be overlooking something simple. Those files are readable by the current user - the debugger shows that the options are simply not getting all the way through, and I don't know why.

Update: With shmem's prodding, I finally got something to "work". It's ugly. I think I'll investigate james2vegas' CB suggestion and look at Net::Server::HTTP quickly, and see if I get something that doesn't need quite so much hacking. However, for posterity, here's what I have:

use strict; use warnings; our $real_stdout; open $real_stdout, '>&', \*STDOUT or die "Can't write to stdout"; my $s = Server->new(@ARGV); $s->background( SSL_cert_file => '/etc/ssl/apache2/server.crt', SSL_key_file => '/etc/ssl/apache2/server.key', ); exit; package Server; use base 'HTTP::Server::Simple::CGI'; sub net_server { 'Net::Server::PreFork::SSL' } package Net::Server::PreFork::SSL; use base 'Net::Server::PreFork'; use Data::Dumper; sub options { my $self = shift; my $prop = $self->{server}; my $ref = shift; $self->SUPER::options($ref); foreach my $p (qw(SSL_cert_file SSL_key_file)) { $prop->{$p} = undef unless exists $prop->{$p}; $ref->{$p} = \$prop->{$p}; } } sub Net::Server::TiedHandle::BINMODE { } #my $s = shift; $s->[1] ? $s- +>[1]->($s->[0], 'binmode', @_) : $s->[0]->binmode(@_) }
It's incomplete since it only includes the SSL_{cert|key}_file keys, not all the keys that SSLEAY supports. But it's a start.

Replies are listed 'Best First'.
Re: SSL with HTTP::Server::Simple and Net::Server
by shmem (Chancellor) on Apr 27, 2011 at 13:20 UTC
    I've run this through the debugger a few times, without quite figuring out how these parameters are supposed to be passed in, nor why they are missing from $s->{server} where Net::Server::Proto::SSLEAY is expecting them.

    That's because the keys SSL_cert_file SSL_key_file are missing from the default structure in sub options from Net/Server.pm line 1338 (as of version 0.99) - it's a bug:

    ### set up default structure sub options { my $self = shift; my $prop = $self->{server}; my $ref = shift; foreach ( qw(port host proto allow deny cidr_allow cidr_deny) ){ if (! defined $prop->{$_}) { $prop->{$_} = []; } elsif (! ref $prop->{$_}) { $prop->{$_} = [$prop->{$_}]; # nicely turn us into an arrayref i +f we aren't one already } $ref->{$_} = $prop->{$_}; } foreach ( qw(conf_file user group chroot log_level log_file pid_file background setsid listen reverse_lookups syslog_logsock syslog_ident syslog_logopt syslog_facility no_close_by_child no_client_stdout tie_client_stdout tied_stdout_callback + tied_stdin_callback leave_children_open_on_hup ) ){ $ref->{$_} = \$prop->{$_}; } }

    Add the keys below leave_children_open_on_hup and presto - it works, at least it doesn't die anymore.

    update: I'm not sure whether it's the right place to add those keys, since the machinery of those modules is hard to grasp with little time at hand. Maybe you should file a bug report.

Re: SSL with HTTP::Server::Simple and Net::Server
by Illuminatus (Curate) on Apr 27, 2011 at 12:21 UTC
    caveat: I have never used this package before

    Did you look at the accept_hook sub-class method? The example on the page is for almost exactly what you are trying to do. If you don't mind embedding your key files directly there, that might be the way to go.

    fnord

      Yes, I did try that. However, and I should have said it originally, I traced it through the code, and accept_hook is only called when not using Net::Server. That is, when using the default built-in server. At first I thought this was a bug. However, then I discovered Net::Server::Proto::SSLEAY, and realised that the way to use Net::Server with HTTP::Server::Simple was to get Net::Server to do the protocol handling instead. Having spent ~4 hours trying to get all this to work with SSL meant that I missed some stuff in my explanation - my apologies for that.

      In fact, it was precisely this example in the doc that made me happy about tye's suggestion to use it in the first place, as it looked like only a few lines of code to get SSL working. Instead, I'm likely to have to at least open a defect against HTTP::Server::Simple to clarify the docs that this is not used in Net::Server integration.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://901426]
Front-paged by tye
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (7)
As of 2024-04-18 17:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found