NAME
HTTP::Server::Brick - Simple pure perl http server for prototyping "in the style of" Ruby's WEBrick
VERSION
This document describes HTTP::Server::Brick version 0.1.7
SYNOPSIS
use HTTP::Server::Brick;
use HTTP::Status;
my $server = HTTP::Server::Brick->new( port => 8888 );
$server->mount( '/foo/bar' => {
path => '/some/directory/htdocs',
});
$server->mount( '/test/proc' => {
handler => sub {
my ($req, $res) = @_;
$res->add_content("<html><body>
<p>Path info: $req->{path_info}</p>
</body></html>");
1;
},
wildcard => 1,
});
$server->mount( '/test/proc/texty' => {
handler => sub {
my ($req, $res) = @_;
$res->add_content("flubber");
$res->header('Content-type', 'text/plain');
1;
},
wildcard => 1,
});
# these next two are equivalent
$server->mount( '/favicon.ico' => {
handler => sub { RC_NOT_FOUND },
});
$server->mount( '/favicon.ico' => {
handler => sub {
my ($req, $res) = @_;
$res->code(RC_NOT_FOUND);
1;
},
});
# start accepting requests (won't return unless/until process
# receives a HUP signal)
$server->start;
For an SSL (https) server, replace the new()
line above with:
use HTTP::Daemon::SSL;
my $server = HTTP::Server::Brick->new(
port => 8889,
daemon_class => 'HTTP::Daemon::SSL',
daemon_args => [
SSL_key_file => 'my_ssl_key.pem',
SSL_cert_file => 'my_ssl_cert.pem',
],
);
See the docs of HTTP::Daemon::SSL for other options.
DESCRIPTION
HTTP::Server::Brick allows you to quickly wrap a prototype web server around some Perl code. The underlying server daemon is HTTP::Daemon and the performance should be fine for demo's, light internal systems, etc.
METHODS
new
new
takes nine named arguments (all of which are optional):
- error_log, access_log
-
Should be self-explanatory - can be anything that responds to
print
eg. file handle, IO::Handle, etc. Default to stderr and stdout respectively. - port
-
The port to listen on. Defaults to a random high port (you'll see it in the error log).
- host
-
The server hostname. Defaults to something sensible.
- timeout
-
Used for various timout values - see HTTP::Daemon for more information.
- directory_index_file
-
The filename for directory indexing. Note that this only applies to static path mounts. Defaults to
index.html
. - directory_indexing
-
If no index file is available (for a static path mount), do you want a clickable list of files in the directory be rendered? Defaults to true.
- leave_sig_pipe_handler_alone
-
HTTP::Daemon, the http server module this package is built on, chokes in certain multiple-request situations unless you ignore PIPE signals. By default PIPE signals are ignored as soon as you start the server (and restored if the server exits via HUP). If you want to handle PIPE signals your own way, pass in a true value for this.
If this makes no sense to you, just ignore it - the "right thing" will happen by default.
- daemon_class
-
The class which actually handles webserving. The default is
HTTP::Daemon
. If you want SSL, useHTTP::Daemon::SSL
. Whatever class you use must inherit from HTTP::Daemon. - daemon_args
-
Sometimes you need to pass extra arguments to your
daemon_class
, e.g. SSL configuration. This arrayref will be dereferenced and passed tonew
. - fork
-
Set to true if you want a forking server.
mount
mount
takes two positional arguments. The first a full uri (as a string beginning with '/' - any trailing '/' will be stripped). The second is a hashref which serves as a spec for the mount. The allowable hash keys in this spec are:
- path
-
A full path to a local filesystem directory or file for static serving. Mutually exclusive with
handler
. - handler
-
A coderef. See "Handlers" below. Mutually exclusive with
path
. - wildcard
-
If false, only exact matches will be served. If true, any requests based on the uri will be served. eg. if
wildcard
is false,'/foo/bar'
will only matchhttp://mysite.com/foo/bar
and not, say,http://mysite.com/foo/bar/sheep
. Ifwildcard
is true, on the other hand, it will match. A handler can access the path extension as described below in "Handlers".Static handlers that are directories default to wildcard true.
The site map is always searched depth-first, in other words a more specific uri will trump a less-specific one.
return value
mount
returns $self
so that it can be chained into a one-liner if desired.
shortcut invocation
As a shortcut also to aid one-liners, instead of a hashref the second argument can be either a path string or a coderef, mapped like so:
- string
-
equivalent to
{ path =
the_string, wildcard => 1 }> - coderef
-
equivalent to
{ handler =
coderef, wildcard => 0 }>
Eg. to quickly server your current directory:
perl -MHTTP::Server::Brick -e 'HTTP::Server::Brick->new(fork=>1)->mount(qw(/ .))->start'
start
Actually starts the server - this will loop indefinately, or until the process recieves a HUP
signal in which case it will return after servicing any current request, or waiting for the next timeout (which defaults to 5s - see "new").
add_type
The mime-type of static files is automatically determined by LWP::MediaTypes. You can add any types it doesn't know about via this method.
The first argument is the mime type, all subsequent arguments form a list of possible file extensions for that mime type. See LWP::MediaTypes for more info.
Handlers
When a mounted handler codred matches a requested url, the sub is called with two arguments in @_
, first a request object then a response object.
Request
The request object is an instance of HTTP::Request with two extra properties:
$req->{mount_path}
-
The mounted path that was matched. This will always be identical to
$req->uri->path
for non-wildcard mounts. $req->{path_info}
-
Using nomenclature from CGI.pm, any extra path (or rather, uri) info after the matched
mount_path
. This will always be empty for non-wildcard mounts.
The documentation for HTTP::Request will be of use for extracting all the other useful information.
Added to the regular request headers created by HTTP::Request is an X-Remote-IP header, which allows you to obtain the remote IP of the client. (Contributed by Hans Dieter Pearcey).
Response
The response object is an instance of HTTP::Response. The useful operations (which you can learn how to do from the HTTP::Response docs) are setting headers, adding content and setting the http status code.
Response Headers
The Content-type
header defaults to text/html
unless your handler sets it to something else. The Content-length
header is set for you.
Redirection
If you set the response code to a redirect code, you need to set a {target_uri}
property on the request object to an instance of a URI::http
object reflecting the uri you want to redirect to (either fully qualified or relative to the directory of the requested url). There are examples in the test file t/serving.t
in this module's distribution.
This is weak because we're breaking encapsulation by assuming it's ok to stuff an extra variable into the response object (just as we are to propogate the path_info
property). It does in fact work fine and is unlikely to ever break, but a future version (prior to 1.0.0) of this module will replace this behavior with a subclassed HTTP::Response and appropriate setter/getter methods.
Handler Return
The handler sub must return true for a normal response. The actual http response is determined as follows:
1. if the handler died or returned false => RC_INTERNAL_SERVER_ERROR (ie. 500)
2. if the handler set a code on the response object, use that
3. if the handler returned something that looks like a return code
4. RC_OK (ie. 200)
DEBUGGING
If an envronment variable DEBUG is set (to something Perl considers true) there will be extra logging to error_log
.
DEPENDENCIES
HISTORY
Over the past few years I've spent quite a bit of time noodling about with Ruby based web code - whether Rails or super cool continuation stuff - and it's always easy to get a prototype up and serving thanks to WEBrick (the pure-Ruby server that's part of the standard Ruby distribution). I've never found it quite as easy to throw together such a prototype in Perl, hence YASHDM (yet another simple http daemon module).
HTTP::Server::Brick is not a clone of WEBrick - it's "in the style of" WEBrick like those movies in the discount VHS bin are "in the style of Lassie": The good guys get saved, the bad guys get rounded up, but the dog's never quite as well trained...
To be more fair, I have just taken the ideas I have used (and liked) when building prototypes with WEBrick and implemented them in (what I hope is) a Perlish way.
BUGS AND LIMITATIONS
- It's version 0.1.7 - there's bound to be some bugs!
- The tests fail on windows due to forking limitations. I don't see any reason why the server itself won't work but I haven't tried it personally, and I have to figure out a way to test it from a test script that will work on Windows.
- In forking mode there is no attempt to limit the number of forked children - beware of forking yourself ;)
- No attention has been given to propagating any exception text into the http error (although the exception/die message will appear in the error_log).
- Versions 1.02 and earlier of HTTP::Daemon::SSL has a feature/documentation conflict where it will never timeout. This means your server won't respond to a HUP signal until the next request is served. Version 1.03_01 (developer release) and later do not have this issue.
If you want to check out the latest development version of HTTP::Server::Brick you can do so from my GitHub account http://github.com/aufflick/p5-http-server-brick.
Please report any bugs or feature requests to bug-http-server-brick@rt.cpan.org
, through the web interface at http://rt.cpan.org or via email to the author.
SEE ALSO
CPAN has various other modules that may suit you better. Search for HTTP::Server or HTTP::Daemon. HTTP::Daemon, HTTP::Daemon::App and HTTP::Server::Simple spring to mind.
AUTHOR
- Original version by: Mark Aufflick
<mark@aufflick.com>
http://mark.aufflick.com/ - SSL and original forking support by: Hans Dieter Pearcey
<hdp@pobox.com>
- Maintained by: Mark Aufflick
LICENCE AND COPYRIGHT
Copyright (c) 2007 2008, Mark Aufflick <mark@aufflick.com>
. Portions Copyright (c) 2007 2008, Hans Dieter Pearcey <hdp@pobox.com>
All rights reserved.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic.
DISCLAIMER OF WARRANTY
BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.