NAME
Plack::Middleware::SubSpec::ParseRequest - Parse HTTP request into SS request
VERSION
version 0.08
SYNOPSIS
# in your app.psgi
use Plack::Builder;
builder {
enable "SubSpec::ParseRequest",
uri_pattern => m!^/api/v1/(?<module>[^?]+)?/?(?<sub>[^?/]+)?!,
allowable_modules => qr/^My::API/;
};
DESCRIPTION
This middleware parses SS request from HTTP request (PSGI environment) and should normally be the first middleware put in the stack.
Parsing result
The result of parsing will be put in 'ss.request' PSGI environment key.
Parsing process
From HTTP header and request body. The parsing is done as per Sub::Spec::HTTP specification. First, all X-SS-Req-*
request headers are parsed for SS request key. When an unknown header is found, HTTP 400 error is returned. Then, request body is read for arguments. 'application/json' document type is accepted, and also 'text/yaml' (if accept_yaml
configuration is enabled) and 'application/vnd.php.serialized' (if accept_phps
configuration is enabled).
Additionally, the following are also done:
From URI. Request URI is checked against uri_pattern configuration. If URI doesn't match this regex, a 400 error response is returned. It is a convenient way to check for valid URLs as well as set SS request keys, like:
qr!^/api/(?<output_format>json|yaml)/!;
Other named captures not matching known SS request keys will be stored in $env->{"ss.uri_pattern_matches"}. For convenience, module
and/or sub
will be used to set uri
(if it's not already defined). For example:
qr!^/api/v1/(?<module>[^?/]+)/(?<sub>[^?/]+)!
will set uri
to "pm:$+{module}/$+{sub}". For convenience, module
is also preprocessed, all nonalphanumeric character groups will be converted to "::".
The default uri_pattern
is qr/.?/, which matches anything, but won't parse/capture any information.
From web form variables. If parse_args_from_web_form
is enabled, args
request key will be set (or added) from GET/POST request variables, for example: http://host/api/foo/bar?a=1&b:j=[2] will set arguments a
and b
(":j" suffix means value is JSON-encoded; ":y" and ":p" are also accepted if the accept_yaml
and accept_phps
configurations are enabled). In addition, request variables -ss-req-*
are also accepted for setting other SS request keys. Unknown SS request key or encoding suffix will result in 400 error.
If request format is JSON and web form variable callback
is defined, then it is assumed to specify callback for JSONP instead part of args
. "callback(json)" will be returned instead of just "json".
From URI (2)
. If parse_args_from_path_info
configuration is enabled, and uri
SS request key contains module and subroutine name (so spec can be retrieved), args
will be set (or added) from URI path info. Note that portion matching uri_pattern
will be removed first. For example, when uri_pattern
is qr!^/api/v1(?:/(?<module>[\w:]+)(?:/(?<sub>\w+)))?!:
http://host/api/v1/Module::Sub/func/a1/a2/a3
will result in ['a1', 'a2', 'a3'] being fed into Sub::Spec::GetArgs::Array. An unsuccessful parsing will result in HTTP 400 error.
CONFIGURATIONS
uri_pattern => REGEX (default qr/.?/)
Regexp with named captures to match against URI, to extract SS request keys from. Additionally,
module
andsub
are also converted into 'pm' URI, ifuri
is not already specified.If regexp doesn't match, a 400 error response will be generated.
allowable_uri_schemes => ARRAY|REGEX (default ['pm'])
Which URI schemes are allowed. If SS request's
uri
has a scheme not on this list, a HTTP 403 error will be returned.allowable_commands => ARRAY|REGEX (default [qw/about call help list_mods list_subs spec usage/])
Which commands to allow. Default is all commands. If you want to disable certain commands, exclude it from the list. In principle the most important command is 'call', while the others are just helpers.
allowable_modules => ARRAY|REGEX (default [])
Which modules to allow. Needs to be set.
parse_args_from_web_form => BOOL (default 1)
Whether to parse arguments from web form (GET/POST parameters). If an argument is already defined (e.g. via X-SS-Req-* HTTP header), it will be skipped.
parse_args_from_path_info => BOOL (default 1)
Whether to parse arguments from path info. This will only be done if
uri
contains module and subroutine name, so its spec can be retrieved (spec is required for parsing from PATH_INFO).removed from URI before args are extracted. Also, parsing arguments from path info (array form,
/arg0/arg1/...
) requires that we have the sub spec first. So we need to execute the Plack::Middleware::SubSpec::LoadSpec first. The actual parsing is done by Plack::Middleware::SubSpec::ParseArgsFromPathInfo first.accept_phps => BOOL (default 1)
Whether to accept PHP serialization-encoded data (either in GET/POST request variables, etc). If you only want to deal with, say, JSON encoding, you might want to turn this off.
accept_yaml => BOOL (default 1)
Whether to accept YAML-encoded data (either in GET/POST request variables, etc). If you only want to deal with, say, JSON encoding, you might want to turn this off.
per_arg_encoding => BOOL (default 1)
Whether we should allow each GET/POST request variable to be encoded, e.g. http://foo?arg1:j=%5B1,2,3%5D ({arg1=>[1, 2, 3]}).
allow_logs => BOOL (default 1)
Whether to allow request for returning log messages (request option 'log_level' with value larger than 0). You might want to turn this off on production servers.
after_parse => CODE
If set, the specified code will be called with arguments ($self, $env) to allow doing more parsing/checks.
SEE ALSO
AUTHOR
Steven Haryanto <stevenharyanto@gmail.com>
COPYRIGHT AND LICENSE
This software is copyright (c) 2011 by Steven Haryanto.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.