or... when we only need a bicycle wheel, sometimes we need to re-invent our wheel slightly to get the job done.
Recently I ran into a situation where a client had a queue system that placed requests into queue files to be processed on another system. Until now, these queue files were created on one machine and network-copied to the processing server. This required a lot of server setup and left a lot of pieces to easily break. It also gave no clear way to log the submission to the queue.
To solve this problem and to make it more easily to integrate, we decided to accept the queue submission via http. We could implement it to take care of these queue files and add some logging and sanity to their current situation. The idea would be to handle a request, validate the submission, log the status and then write the given request to the queue directory.
Seems simple right?
Right.
The problem is, we didn't want to install an entire httpd like nginx, or lighttpd, and likewise a Catalyst application for this type of thing would be somewhat overcomplicated, as there was really only be one action to be done.
So what's our solution? We need a simple, light, and forkable http server that can take our requests and process them so.
Enter HTTP::Server::Simple. This is a lightweight, Perl based server module that will allow you to subclass any number of its "flavors" to suit your needs. It comes with the option to prefork, that is, start $x number of instances to fit your traffic load, use CGI like parameters and response/request handling, as well as easy url dispatching (set up a hash of your url->method mapping, pass that to the handler method, done).
You also have the option of writing hooks into various aspects, for instance accept_hook allows you to do something along these lines to allow for SSL encryption:
sub accept_hook {
my $self = shift;
my $fh = $self->stdio_handle;
$self->SUPER::accept_hook(@_);
my $newfh =
IO::Socket::SSL->start_SSL( $fh,
SSL_server => 1,
SSL_use_cert => 1,
SSL_cert_file => 'myserver.crt',
SSL_key_file => 'myserver.key',
)
or warn "problem setting up SSL socket: " . IO::Socket::SSL::errstr();
$self->stdio_handle($newfh) if $newfh;
}
That's pretty cool. Here's a basic set up that allows you to dispatch to a single and simple method (from the docs):
#!/usr/bin/perl
{
package MyWebServer;
use HTTP::Server::Simple::CGI;
use base qw(HTTP::Server::Simple::CGI);
my %dispatch = (
'/hello' => \&resp_hello,
# ...
);
sub handle_request {
my $self = shift;
my $cgi = shift;
my $path = $cgi->path_info();
my $handler = $dispatch{$path};
if (ref($handler) eq "CODE") {
print "HTTP/1.0 200 OK\r\n";
$handler->($cgi);
} else {
print "HTTP/1.0 404 Not found\r\n";
print $cgi->header,
$cgi->start_html('Not found'),
$cgi->h1('Not found'),
$cgi->end_html;
}
}
sub resp_hello {
my $cgi = shift; # CGI.pm object
return if !ref $cgi;
my $who = $cgi->param('name');
print $cgi->header,
$cgi->start_html("Hello"),
$cgi->h1("Hello $who!"),
$cgi->end_html;
}
}
# start the server on port 8080
my $pid = MyWebServer->new(8080)->background();
print "Use 'kill $pid' to stop server.\n";
Really really simple. This is a really neat tool that allows you to add a great deal of flexibility in a pinch.
Next time I'll show you a more complete request processor built with HTTP::Server::Simple... stay tuned.




HTTP::Server::Simple may be handy, but it has one massive flaw. It doesn't work at all on Windows.
So it's a handy little tool for private or commercial code that will only ever run on Unix, but it's next to useless for public, crossplatform or CPAN code.
Which is why it's such a pity that WWW::Mechanise and a zillion other things use it, because it means all of those don't work on Windows either.
Also - Does Net::Server also not work on windows? That's what HTTP::Server::Simple uses.
Does anyone have a suggestion for an alternative to HTTP::Server::Simple?
Is not working under Windows really a "massive flaw"?
It's a massive flaw if you want to use it on a Windows machine.
Yours,
3om
Tom DeGisi
I have to agree that "not working under windows" doesn't necessarily rank high on my "stuff I care about list" :-)
But, truth be told, people use windows, therefore it would be helpful if the portability of a tool was factored into the usefulness of said tool.
Yes, as Jay asked, does anyone have any alternative suggestions? I'll prod around as well.
Thanks for the feedback!
Saying "It doesn't work at all on Windows" is probably too strong statement. The reality is not not good but not so dark.
1) The example posted by dhoss works on Win32 (apart from going into background and possibility to use kill) - tested on my win32 strawberry perl 5.8.9
2) Yes, HTTP::Server::Simple does not install smoothly as it has some failing tests on Win32. But the reason is AFAIK primarily purely written tests.
3) The module is definitely Win32 unfriendly and the author does not care about Win32 compatibility too much (see many unsolved Win32 RTs)
4) The cause of the problems (and not only with HTTP::Server::Simple) is in my opinion unawareness of the module author about perl@Windows vs. perl@UNIX differences and using some UNIX specific tricks. The quite frequent problem regards using fork (used in background function of HTTP::Server::Simple) as on Win32 fork is emulated via threads and works slightly differently than "original" UNIX fork - but I stress again "perl fork works on Win32", however the fork emulation for example means that used module has to be thread-safe.
BTW: HTTP::Server::Simple + Class::Throwable are the only 2 modules with failing tests on Win32 in the whole Catalyst::Runtime dependency chain.
--
kmx
kmx - thanks for the insight. You got to the Windows answers much faster than I would have!
For the record, I just (9/29/2009) installed Strawberry Perl and this package on a Windows-XP (yuck! ;-) ) machine and it worked perfectly.
I had hoped to use "HTTP::Server::Brick" but that package ran afoul of "POSIX macro 'sighup' is not defined."
Anyhow, the situation wrt Windows implementations of Perl is changing rapidly. Windows is different ... (“ ... if I on-ly had a brain ...”) ... but the mainstream implementations of Perl on that platform do seem to be getting better, fast.
I hope that CPAN package-maintainers will continue to make the extra effort to test their software on Windows as well as Unix/Linux system types, when they know that their packages rely upon lower-level OS features, such as signals and threads, where inherent differences are known to exist. Perl is a breath of fresh-air in that tools-starved environment, and those of us who know about Perl love to apply it, to great effect.