Guide Home
POD Home

Sloop::Server

DESCRIPTION

This is the fundamental sloop server class. It is a subclass of Sloop::Base.

SYNOPSIS

 my $sloop = Sloop::Server->new (
     client_constructor => (optional) sub ref
     debug => (optional) integer
     groups => (optional) array ref
     id => (optional) see Sloop::Base
     IPv => (optional) 4 or 6
     lastwords => (optional) sub ref
     logger => (optional) Sloop::Logger object
     options => (optional) see below; default 1
     pollwait => (optional) integer seconds
     port => (optional) integer
     queue_sz => (optional) integer
     secure => (optional) hash ref
     sigpipe => (optional) scalar or sub ref
     timeout => (optional) integer seconds
     uid => (optional) integer
     virtualHosts => (optional) hash ref
         bindAddr => undef
 );

The default for 'id' is 'MAIN'. The other options are described below.

client_constructor

This must be from a Sloop::Client derived class. It should NOT be a simple coderef such as \&Sloop::Client::Regular::new. Instead, use the following form:

 client_constructor => sub {
     Sloop::Client::Regular->new (
         @_,
         debug => DBG_INPUT
     );
 }

In this example, the 'debug' value will override any in @_ passed by the sloop server.

debug

Zero, or one or more of the 'Debug Constants' from Sloop::Constants added (or OR'd) together. Unless specifically overridden in the client_constructor, this is also the debug value passed to new client objects. The default is 0.

groups

If defined, this should be an array of supplementary group names or GIDs to add for the server process. This happens both before port binding and the assignment of a UID, if specified.

IPv

Valid values are either 4 (the default) or 6. When using IPv6, Sloop will run in "dual stack" mode; i.e., IPv4 clients will be accepted as IPv6 clients (see man 7 ipv6). The default is 4.

lastwords

An optional subroutine reference; if defined it will be called in shut(), e.g., when the object is destroyed.

logger

An object matching the specifications of Sloop::Logger. If not defined Sloop::Logger will be included via 'require' to create the default. Unless specifically overridden in the client_constructor, this is also the logger value passed to new client objects.

options

This is enabled by default by setting it to 1, but it can be disabled by setting it to undef or an empty hash.

If defined and NOT a hash reference, Sloop will require Getopt::Std and process the following options in the following order. Subsequently, $self->{options} will be a reference to the hash from getopts(). If defined and a hash reference, that will be processed as if returned from getopts (meaning, all actual command line options will be ignored).

In either case, these take precedence over anything set by other constructor arguments.

-1 [path]

STDOUT will be redirected to the specified file path. If this path is just '2', it will be redirected to STDERR.

-2 [path]

STDERR will be redirected to the specified file path. If this path is just '1', it will be redirected to STDOUT.

-a [address string]

Corresponds to `bindAddr`.

-d

(Daemonize) When $sloop->run is called, the process will fork into the background, setsid, and redirect STDIN from /dev/null. It does NOT change directory.

-g [debug constants]

The argument is one or more of the keys to DebugConstants or'd together, sans DBG_ and case insensitive, e.g., "request | reply" or "connection". This will replace any value submitted to the constructor's optional 'debug' argument, so no argument will turn debugging output off.

-p [port number]

A port number to use.

pollwait

Time in seconds to return from the internal epoll() call if nothing happens (no requests are received, no replies are ready). Perhaps more significantly, this is also the frequency with which sloop checks client timeouts, regardless of whether epoll ever times out or not (the frequency of the check is not the same as the timeout length, see 'timeout' below). The default is 15.

port

The port to use. The default is 80. You may use zero, in which case the system will assign a random open port; this is accessible after the constructor call via $sloop->{port}.

queue_sz

The maximum wait queue length to pass to listen(). The default is 500.

secure

If defined, this will make sloop run in secure (https) mode using gnuTLS. The argument is a hash ref with same keys described for the arguments to Sloop::Socket::TLS:init(); Required are at least the 'certificateChain' and 'privKey' fields.

If you specify this and use a custom client_constructor as well, be sure it is Sloop::Client::Secure based.

sigpipe

By default the constructor sets $SIG{PIPE} = "IGNORE"; you can override that with this (or set it differently post construction). See "Signals" in perlipc.

timeout

The lifespan of a persistent connection in seconds. This only applies when awaiting a new request -- clients in the middle of an upload, or in need of a reply, will not be timed out. The default is 30. Note that if there is no activity, the timeout will be checked when the server epoll() times out; since this value is set with `pollwait` (above), it makes sense to set `timeout to some multiple of `pollwait` (but it is not required to be).

uid

If defined, the sloop process will setuid and gid to this value after the server socket has been initialized. Note that (as per normal), doing this does not include any of the other groups the user represented by uid is a member of, but you can add any you want via the groups option above. A numerical id or string username can be used.

virtualHosts

If you want to use name based virtual hosting, you can define this instead of {handlers} (see ATTRIBUTES). The top level keys of the hash should be the hostnames in all lower case. Their values should be hash references identical to {handlers}.

Note that name based virtual hosting won't work with HTTP 1.0 clients that don't include a 'Host:' header (HTTP 1.1 clients are required to). If you want to do something special with these, define default as one of the hosts. If this is not defined, the client receives a 404.

=itembindAddr

By default sloop binds to 0.0.0.0, the "all interfaces", aka. INADDR_ANY, address. Generally speaking this is what you want, but in some circumstances (eg. multiple interfaces and you only want to use one, or to restrict access to the loopback) you may want to be more specific. This must be an IPv4 or v6 address in dot decimal or (IPv6) colon hexadecimal format.

ATTRIBUTES

In addition to the attributes listed for Sloop::Base, the following fields from the constructor are accessible by the same name, with the same meaning:

client_constructor
groups*
IPv*
lastwords
options*
pollwait
port*
queue_sz*
timeout
uid*
virtualHosts
bindAddr*

An asterisk indicates changing this field won't have any effect.

$sloop->{handlers}

You need to define this before you call $sloop->run. It should be a hash ref reference whose values are either further hash references or subroutine references. Sloop cascades through this to resolve paths. For example:

 $sloop->{handlers} = {
     '/' => \&handlerA,
     foo => {
         '/' => \&handlerB,
         bar => \&handlerC
     },
     banana => \&handlerD
 };

'/' represents the relative top level, so in this case,

- Requests beginning with /foo/bar/ will go to handlerC.
- Requests beginning with /foo/ but not /foo/bar/ will go to handlerB.
- Requests beginning with /banana/ will go to handlerD.
- All other requests will go to handlerA.

Notice this means any request beginning with /foo/bar (of which there is obviously an infinite number) will go to handlerC, and likewise any request beginning with /banana (e.g., /banana/apple/cherry) will go to handlerD, etc. This can be delimited by using a special array format instead, as described below. The handler itself receives one argument, a Sloop::Client derived object with a Sloop::Client::Request attached. Its return value is ignored.

Sloop will automatically prune '..' out of any path, so '/foo/../bar' will be handled as '/foo/bar/'. No redirect is sent to the client, but note the URL will be stable this way.

Alternately, a handler may be an array reference of the form:

 '/' => [ \&handler, $min, $max ]

in order to invoke Sloop::Lib::checkURL($client, $min, $max) before the callback fires (which will only happen if this check succeeds). This is an easy way of controlling the number of path elements accepted beyond the end of the cascade. As per checkURL() parameters, the last two elements are optional.

For more discussion about this and handlers in general, see the HTML guide page on "Request Handling".

$sloop->{secure}

If defined, this is an HTTPS server using TLS 1.0 for client connections. If not, it is a regular HTTP server. You should not change this field. Unlike the constructor 'secure' parameter, this does not contain any actual information, it is just defined (or not).

ENVIRONMENT VARIABLES

The constructor sets the variable $ENV{SLOOP_PROTOCOL} to either "http://" or "https://", as appropriate, so this will be inherited by any subprocess. You may also make use of it in your code, presuming it executes after the constructor call.

SIGNAL HANDLERS

As noted in SYNOPSIS, by default Sloop sets $SIG{PIPE} = "IGNORE".This may occur because of violations of or failures in low level protocols -- e.g., sudden, inappropriate disconnections. Such defunct connections will be discarded.

METHODS

$sloop->connectOther($other)

$other is a Sloop::Other derived object.

Used to add a Sloop::Other connection to the server. This is necessary in order to make use of $other for sending and receiving messages. It adds a reference to the server's FD list which should be purged when $other is shut/defunct, so holding additional references are not required.

Returns undef if $other is undefined or defunct (as indicated by $other->okay), and a true value otherwise.

$sloop->epollSize()

This returns the number of connections still being actively polled. This includes the server listen socket, so it is normally at least 1; the server will stop running within $sloop->{timeout} seconds if there are none. See stopListening(), below, for how that might happen.

$sloop->run()

Starts the server main loop. The call blocks until the server stops running.

$sloop->stopListening()

This will close the server listening socket, meaning it will no longer accept new connections; it will continue to service existing ones. When there are no more left, it will stop stop running.