Skip to content

ap/Plack-Middleware-Static-Precompressed

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NAME

Plack::Middleware::Static::Precompressed - serve a tree of static pre-compressed files

SYNOPSIS

use Plack::Builder;

builder {
    enable 'Static::Precompressed',
                root => 'static',
                path_info => '^static/(.*)';
    $app;
};

DESCRIPTION

This middleware does HTTP content negotiation based on content encoding, given a set of files that never change. It is meant primarily as a complement to middlewares such as Deflater which compress each response on the fly – as is necessary for generated responses, but wasteful when it repeats the same work for the same unchanged files over and over again. This middleware lets you compress each static asset file just once, e.g. as part of your build process, then at runtime just picks the smallest one that the client can use.

If a URL is not matched, it is passed to the wrapped PSGI application. But you can also use this middleware as a standalone PSGI application, in which case it will return a 404 response for URLs it does not have. If you would like to use it like this but dislike instantiating a middleware, you can use the included dummy Plack::App::File::Precompressed wrapper.

CONFIGURATION OPTIONS

files

An array of file paths to pass to "add_file".

Size and modification time will be retrieved from stat.

root

The path of a directory to search for files to pass to "add_file".

Only files which pass the -f test will be used.

Size and modification time will be retrieved from stat.

File::Find will be loaded if you pass this option, but not otherwise.

path_info

A pattern or a callback which will be used by "add_file" to get the HTTP metadata for each file.

path_info => '^static/(.*)',

If it is a pattern (string or qr object), each file path will be matched against the pattern, and if successful, the first capture ($1) will be used as the URI path for the file. The /s flag will be enabled on the match (which only affects patterns passed as strings, not qr objects).

path_info => sub {
  my ( $path, $headers ) = @_;
  # ...
  return ( $uri_path, $content_encoding );
},

If it is a callback, it will be called for each file and passed the file path and a reference to a headers array. The callback may mutate the headers array and/or return a list consisting of a URI path and a content encoding. Both values may be undefined.

ext_map

A hash that maps file extensions to content encodings, used by "add_file".

Defaults to { gz => 'gzip', br => 'br' }.

default_charset

Charset to use for files with a text/* MIME type from Plack::MIME, used by "add_file".

Defaults to utf-8.

response_cb

A Plack::Util::response_cb callback for the reponse. You may want to use something like inject_headers from Plack::Middleware::NeverExpire here.

max_file_size

Maximum size in bytes of files to read into memory on startup.

Defaults to 8192 bytes.

You can set this to 0 to disable buffering or 9**9**9 to disable the limit.

max_total_size

Maximum amount of data in bytes to read into memory at startup.

Defaults to 8 megabytes.

Files will be prioritized by increasing size.

You can set this to 0 to disable buffering or 9**9**9 to disable the limit.

max_open_files

Maximum number of open filehandles to cache.

Defaults to 128.

This applies to files larger than "max_file_size".

You can set this to 0 disable filehandle caching.

handle_cb

A callback that is passed a file path and returns a handle.

Defaults to a wrapper around open.

The handle must be a PSGI-compatible body filehandle (i.e. an object with getline and close methods), but with one additional requirement: instead of closing the file, close must do (the equivalent of) seek $fh, 0, 0.

This option allows you to completely isolate this middleware from the real filesystem, provided you also use neither the "files" nor "root" options, and that all your calls to "add_file" or "add_files" explicitly pass a size for all files.

fh_error_cb

A callback that is called if an error is encountered while trying to open a file at runtime.

Defaults to throwing an exception.

The callback is passed a file path and expected to return a PSGI response (if it does return).

METHODS

add_file

Takes a file path and size and optionally a modification time and registers the file to be served at runtime:

$app->add_file( $path, $size, $mtime );

This takes care of assigning a URI path to each file. Different versions of the same file (e.g. styles.css and styles.css.gz) need to be assigned the same URI path (e.g. /styles.css) but with different content encodings (e.g. none and gzip, respectively, in this case).

When some known URI path is requested, the middleware will respond with the smallest file that the client supports.

The unencoded file for a URI path is by definition supported, and is given priority over any other versions that are not smaller. This means that any encoded file which is not smaller than its unencoded version will be ignored entirely.

Each URI path must have a file without a content encoding.

The "path_info" configuration option, if set, is asked for the URI path for the file. If it is a callback and does not return a true value as the URI path, or if it is a pattern and it does not match the file path, then the file path itself will be used as the URI path.

The URI path will addtionally be normalized to begin with a / regardless of whether it starts with / or ./ or neither.

If no "path_info" callback is given or the returned content encoding is undefined then the URI path will be matched against the extensions given in the "ext_map" option. If a match is found, the file will be assigned to the URI path without the extension, with the corresponding encoding.

If the "path_info" callback does not add a Content-Type header to the headers array then Plack::MIME will be loaded and passed the URI path to set a default MIME type; for text/* MIME types, the "default_charset" will be added.

add_files

Takes a list of arrays to pass as arguments to "add_file". In other words,

$app->add_files( [ 'foo', 48 ], [ 'boot', 96 ] );

does the same as

$app->add_file( 'foo', 48 );
$app->add_file( 'boot', 96 );

SEE ALSO

Plack::Middleware::Deflater

Plack::Middleware::Precompressed is effectively obsoleted by this middleware.