Guide Home
POD Home

Sloop::Static

DESCRIPTION

Several independent functions for dealing with static directory content. Sloop::Static::directory() will read static files from a directory and deliver them via the server to a Sloop::Client. Sloop::Static::index() will output an html list of links for each file in a directory.

REQUIRES

This refers only to modules not part of Sloop or the perl core.

URI::Encode

Sloop::Static::directory()

This function will return the contents of a file to a client, if it is found in a given directory tree. Note that the path used, relative to the given tree, is the same as the path in the array returned by Sloop::Client::pathFromLevel(). For example, if the complete request path is /wherever/static/foo/bar/file.html and you have handlers like this:

 $sloop->{handlers} = {
     wherever => {
         static => sub {
             Sloop::Static::directory (
                 shift,
                 path => '/opt/sloop/static/',
             );
         }
     }
 };

The "pathFromLevel" would be /foo/bar/file.html, thus the file searched for would be /opt/sloop/static/foo/bar/file.html. If this path leads to a directory and the request path did not terminate in a forward slash, a 301 redirect to the same path, with / appended, is issued (but see "A Note About Hostname", below). This allows you to use, e.g., an 'index.html' which references relative paths -- href='whatever.css', etc. -- since otherwise browsers will assume the path is one level up. If the path is /foo/bar, 'whatever.css' will result in a request for /foo/whatever.css; if the the path is /foo/bar/, it will be /foo/bar/whatever.css, which is probably what you want, since /foo/bar/ will be expanded to /foo/bar/index.html (see the 'index' argument below for more about this last point).

This relationship to "pathFromLevel" also affects whether or not '..' links are shown if no index.html file or function is found for the location. This means if you do not provide indexes and just used the ones automatically provided by Sloop::directory::index(), below, the user will be able to travel up and down but not up and out of the tree.

Only $client->{max_send} bytes will actually be read into memory at once; see buffer_data under Sloop::Connection ATTRIBUTES regarding how this is done.

The arguments are:

 Sloop::Static::directory(
    $client,
    path => [REQUIRED],
        extra => [OPTIONAL]
    index => [OPTIONALAL],
    maxage => [OPTIONAL],
    mimetype => [OPTIONAL]
 );
$client

A Sloop::Client derived object.

path (REQUIRED)

Base absolute path to use.

extra

Hash ref of extra HTTP headers to use, e.g.,

 extra => {
        'Content-Disposition' => 'inline'
 }
index

A handler to pass $client to if the path ends with a directory. Nothing more is done in this case. If undefined, "index.html" is appended and the lookup proceeds. If this file does not exist, Sloop::Static::index() is used. If you don't want that, use a value that responds to if (defined && !ref), e.g. index => 1.

maxage

A time in seconds to pass to $client->reply() for use in the 'Cache-Control: max-age=' HTTP header. If non-existant, the $client->{maxage} is used.

mimetype

The mime type to use with the 'Content-Type' header. If undefined, this is determined via Sloop::Static::Mimetype::get(), and if that fails, defaults to 'text/plain'.

A Note About Hostname: Doing a redirect requires a complete URI for the 'Location:' header. Since the 'Host:' field is mandatory in the request for HTTP 1.1 clients, this is straightforward enough. However, HTTP 1.0 clients can accept a redirect, but may not have included a 'Host:' field, and in that case, a value from `hostname` is used (see Sloop::Client::Request::hostURI()). If this is incorrect, so will be the redirect. If it turns out that the hostname command is unavailable on the system, the client will recieve a 404.

If you are using virtual hosts, don't worry about this as it only works for clients which include a 'Host:' anyway.

Sloop::Static::index ()

Creates a simple HTML unordered list (<ul>) indexing the files in a directory.

 my $html = Sloop::Static::index (
        path => (required) scalar,
        url => (optional) scalar,
        dots => (optional) defined/non-zero or undef/0,
        sort => (optional) sub ref,
        filter => (optional) sub ref,
        logger => (optional) Sloop:logger object; undef default.
 );
path

Absolute path to the directory to index.

url

String to append to the filename for an href, otherwise just the filename is used. You probably don't need this.

dots

If 0 or undef (the default), the '..' directory entry will be discarded, otherwise it will be kept ('.' is always discarded).

sort

If defined, this should be a subroutine reference. The routine receives the array of files from the directory, and should return an array. If undefined, perl's default lexicographical sort is used.

filter

If defined, this should be a subroutine reference which will receive a reference to the array of files, and should return an array. This is done before sort(), above. Note though that if you want to do both things (filter or modify the list, then sort it), you might as well do it in sort().

logger

If defined, somewhere to explain an error -- this is used when called from Sloop::Static::directory.

Returns an html string.