NAME
HTTP::Server::Singlethreaded - a framework for standalone web applications
SYNOPSIS
# configuration first:
#
BEGIN { # so the configuration happens before import() is called
# static directories are mapped to file paths in %Static
$HTTP::Server::Singlethreaded::Static{'/images/'} = '/var/www/images';
$HTTP::Server::Singlethreaded::Static{'/'} = '/var/www/htdocs';
#
# configuration for serving static files (defaults are shown)
$HTTP::Server::Singlethreaded::DefaultMimeType = 'text/plain';
@HTTP::Server::Singlethreaded::MimeType{qw/txt htm html jpg gif png/} =
qw{text/plain text/html text/html image/jpeg image/gif image/png};
#
# internal web services are declared in %Functions
$HTTP::Server::Singlethreaded::Function{'/AIS/'} = \&HandleAIS;
#
# external CGI-BIN directories are declared in %CgiBin
# NOT IMPLEMENTED YET
$HTTP::Server::Singlethreaded::CgiBin{'/cgi/'} = '/var/www/cgi-bin';
#
# @Port where we try to listen
@HTTP::Server::Singlethreaded::Port = (80,8000);
#
# Timeout for the selecting
$HTTP::Server::Singlethreaded::Timeout = 5
#
# overload protection
$HTTP::Server::Singlethreaded::MaxClients = 10
#
}; # end BEGIN
# merge path config and open listening sockets
use HTTP::Server::Singlethreaded;
#
# "top level select loop" is invoked explicitly
for(;;){
#
# manage keepalives on database handles
if ((time - $lasttime) > 40){
...
$lasttime = time;
};
#
# do pending IO, invoke functions, read statics
# HTTP::Server::Singlethreaded::Serve()
Serve(); # this gets exported
}
DESCRIPTION
HTTP::Server::Singlethreaded is a framework for providing web applications without using a web server (apache, boa, etc.) to handle HTTP.
CONFIGURATION
One of %Static, %Function, %CgiBin should contain a '/' key, this will handle just the domain name, or a get request for /.
%Static
the %Static hash contains paths to directories where files can be found for serving static files.
%Function Paths to functions => functions to run. Functions should take exactly one argument, which will be the entire server request.
%CgiBin
CgiBin is a functional wrapper that forks and executes a named executable program, after setting the common gateway interface environment variables and changing directory to the listed directory. NOT IMPLEMENTED IN THIS VERSION
@Port
the @Port
array lists the ports the server tries to listen on.
name-based virtual hosts
not implemented yet; a few configuration interfaces are possible, most likely a hash of host names that map to strings that will be prepeneded to the key looked up in %Path.
$Timeout
the timeout for the select
$MaxClients
if we have more active clients than this we won't accept more. Since we're not respecting keepalive at this time, this number indicates how long of a backlog singlethreaded will maintain at any moment.
$WebEmail
an e-mail address for whoever is responsible for this server, for use in error messages.
$forkwidth
Set $forkwidth to a number greater than 1 to have singlethreaded fork after binding. If running on a multiprocessor machine for instance, or if you want to verify that the elevator algorithm works. After import()
, $forkwidth is altered to indicate which process we are in, such as "2 of 3". The original gets an array of the process IDs of all the children in @kids, as well as a $forkwidth variable that matches /(\d+) of \1/
. Also, all children are sent a TERM signal from the parent process's END block. Uncomment the relevant lines if you need this.
$uid and $gid
when starting as root in a *nix, specify these numerically. The process credentials will be changed after the listening sockets are bound.
Dynamic Reconfiguration
Dynamic reconfiguration is possible, either by directly altering the configuration variables or by passing references to import(). If you can't see how to do this from looking at the source, an attempted explanation here would probably just waste your time.
Action Selection Method
The request is split on slashes, then matched against the configuration hashes until there is a match. Longer matching pieces trump shorter ones.
Having the same path listed in more than one of %Static, %Functions, or %CgiBin is an error and the server will not start in that case.
Writing Functions For Use With HTTP::Server::Singlethreaded
This framework uses the %_
hash for passing data between elements which are in different packages.
Data you get
the whole enchilada
The full RFC2616-sec5 HTTP Request is available for inspection in $_
. Certain parts have been parsed out and are available in %_
. These include
Method
Your function can access all the HTTP methods. You are not restricted to GET or POST as with the CGI environment.
URI
Whatever the client asked for.
HTTPver
such as 1.1
QUERY_STRING, PATH_INFO
as in CGI
Data you give
The HandleRequest() function looks at two data only:
ResultCode
$_{ResultCode}
defaults to 200 on success and gets set to 500 when your function dies. $@
will be included in the output. Singlethreaded knows all the result code strings defined in RFC2616.
Data
Store your complete web page output into $_{Data}
, just as you would write output starting with server headers when writing a simple CGI program. Or leave $_{Data} alone and return a valid page, beginning with headers.
AVOIDING DEADLOCKS
The server blocks while slurping files and executing functions, at this version. So singlethreaded is not appropriate for serving large files.
What Singlethreaded is good for
Singlethreaded is designed to provide a web interface to a database, leveraging a single persistent DBI handle into an unlimited number of simultaneous HTTP requests.
HISTORY
- 0.01
-
August 18-22, 2004. %CgiBin is not yet implemented.
- 0.02
-
August 22, 2004. Nonblocking sockets apparently just plain don't exist on Microsoft Windows, so on that platform we can only add one new client from each listener on each call to serve.
EXPORTS
Serve()
is exported.
AUTHOR
David Nicol <davidnico@cpan.org>
This module is released AL/GPL, the same terms as Perl.
References
Paul Tchistopolskii's public domain phttpd
HTTP::Daemon
the University of Missouri - Kansas City Task Definition Interface
perlmonks