NAME
Plack::Middleware::PeriAHS::ParseRequest - Parse Riap request from HTTP request
VERSION
This document describes version 0.620 of Plack::Middleware::PeriAHS::ParseRequest (from Perl distribution Perinci-Access-HTTP-Server), released on 2017-12-09.
SYNOPSIS
# in your app.psgi
use Plack::Builder;
builder {
enable "PeriAHS::ParseRequest",
match_uri => m!^/api(?<uri>/[^?]*)!;
};
DESCRIPTION
This middleware's task is to parse Riap 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 $env->{"riap.request"}
hashref.
Aside from that, this middleware also sets these for convenience of later middlewares:
$env->{'periahs.default_fmt'} => STR
Default output format, will be used for response if
fmt
is not specified in Rinci request. Determined using some simple heuristics, i.e. graphical browser like Firefox or Chrome will get 'HTML', command-line browser like Wget or Curl will get 'Text', others will get 'json'.$env->{'periahs.jsonp_callback'} => STR
From form variable
callback
.$env->{'periahs.riap_client'} => OBJ
Store the Riap client (by default instance of Perinci::Access::Schemeless).
Parsing process
From HTTP header and request body. First parsing is done as per Riap::HTTP specification's requirement. All X-Riap-*
request headers are parsed for Riap request key. When an unknown header is found, HTTP 400 error is returned. Then, request body is read for args
. application/json
document type is accepted, and also text/yaml
(if accept_yaml
configuration is enabled).
Additionally, the following are also done:
From URI. Request URI is checked against match_uri configuration (This step will be skipped if match_uri configuration is not set or empty). If URI doesn't match this regex, a 404 error response is returned. It is a convenient way to check for valid URLs as well as set Riap request keys, like:
qr!^/api/(?<fmt>json|yaml)/!;
The default match_uri
is qr/(?<uri>[^?]*)/.
From form variables. If parse_form configuration 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" is also accepted if the accept_yaml
configurations are enabled). In addition, request variables -riap-*
are also accepted for setting other Riap request keys. Unknown Riap request key or encoding suffix will result in 400 error.
If request format is JSON and 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 form variables (2, ReForm). PeriAHS has support for ReForm. If parse_reform configuration is set to true and form variable -submit
is also set to true, then the resulting args
from previous step will be further fed to ReForm object. See the "parse_reform" in the configuration documentation.
From URI (2, path info)
. If parse_path_info
configuration is enabled, and uri
Riap request key has been set (so metadata can be retrieved), args
will be set (or added) from URI path info. See "parse_path_info" in the configuration documentation.
http://host/api/v1/Module::Sub/func/a1/a2/a3
will result in ['a1', 'a2', 'a3'] being fed into Perinci::Sub::GetArgs::Array. An unsuccessful parsing will result in HTTP 400 error.
CONFIGURATIONS
riap_uri_prefix => STR (default: '')
If set, Riap request
uri
will be prefixed by this. For example, you are exposing Perl modules atYourApp::API::*
(e.g.YourApp::API::Module1
. You want to access this module via Riap request uri/Module1/func
instead of/YourApp/API/Module1/func
. In that case, you can set riap_uri_prefix to/YourApp/API/
(notice the ending slash).server_host => STR
Set server host. Used by get_http_request_url. The default will be retrieved from PSGI environment
HTTP_HOST
.server_port => STR
Set server port. Used by get_http_request_url. The default will be retrieved from PSGI environment
HTTP_HOST
.server_path => STR (default: '/api')
Set server URI path. Used by
get_http_request_url
.get_http_request_url => CODE (default: code)
Should be set to code that returns HTTP request URL. Code will be passed
($self, $env, $rreq)
, where$rreq
is the Riap request hash. The default code will return something like:http(s)://<SERVER_HOST>:<SERVER_PORT><SERVER_PATH><RIAP_REQUEST_URI>
for example:
https://cpanlists.org/api/get_list
This code is currently used by the PeriAHS::Respond middleware to print text hints.
Usually you do not need to customize this, you can already do some customization by setting server_path or riap_uri_prefix, unless you have a more custom URL scheme.
match_uri => REGEX or [REGEX, CODE] (default qr/.?/)
This provides an easy way to extract Riap request keys (typically
uri
) from HTTP request's URI. Put named captures inside the regex and it will set the corresponding Riap request keys, e.g.:qr!^/api(?<uri>/[^?]*)!
If you need to do some processing, you can also specify a 2-element array containing regex and code. When supplied this, the middleware will NOT automatically set Riap request keys with the named captures; instead, your code should do it. Code will be supplied ($env, \%match) and should set $env->{'riap.request'} as needed. An example:
match_uri => [ qr!^/api (?: /(?<module>[\w.]+)? (?: /(?<func>[\w+]+) )? )?!x, sub { my ($env, $match) = @_; if (defined $match->{module}) { $match->{module} =~ s!\.!/!g; $env->{'riap.request'}{uri} = "/$match->{module}/" . ($match->{func} // ""); } }];
Given URI
/api/Foo.Bar/baz
,uri
Riap request key will be set to/Foo/Bar/baz
.match_uri_errmsg => STR
Show custom error message when URI does not match
match_uri
.accept_yaml => BOOL (default 0)
Whether to accept YAML-encoded data in HTTP request body and form for
args
Riap request key. If you only want to deal with JSON, keep this off.parse_form => BOOL (default 1)
Whether to parse
args
keys and Riap request keys from form (GET/POST) variable of the name-x-riap-*
(notice the prefix dash). If an argument is already defined (e.g. from request body) or request key is already defined (e.g. fromX-Riap-*
HTTP request header), it will be skipped.parse_reform => BOOL (default 0)
Whether to parse arguments in
args
request key using ReForm. Even if enabled, will only be done if-submit
form variable is set to true.This configuration is used only if you render forms using ReForm and want to process the submitted form.
Form specification will be created (converted) from
args
property in function metadata, which means that ameta
Riap request to the backend will be performed first to get this metadata.parse_path_info => BOOL (default 0)
Whether to parse arguments from $env->{PATH_INFO}. Note that this will require a Riap
meta
request to the backend, to get the specification for function arguments. You'll also most of the time need to prepare the PATH_INFO first. Example:parse_path_info => 1, match_uri => [ qr!^/ga/(?<mod>[^?/]+)(?: /?(?: (?<func>[^?/]+)?: (<pi>/?[^?]*) ) )!x, sub { my ($env, $m) = @_; $m->{mod} =~ s!::!/!g; $m->{func} //= ""; $env->{'riap.request'}{uri} = "/$m->{mod}/$m->{func}"; $env->{PATH_INFO} = $m->{pi}; }, ]
riap_client => OBJ
By default, a Perinci::Access::Schemeless object will be instantiated (and later put into
$env-
{'periahs.riap_client'}> for the next middlewares) to perform Riap requests. You can supply a custom object here, for example the more general Perinci::Access object to allow requesting from remote URLs.use_tx => BOOL (default 0)
Will be passed to Perinci::Access::Schemeless constructor.
custom_tx_manager => STR|CODE
Will be passed to Perinci::Access::Schemeless constructor.
php_clients_ua_re => REGEX (default: qr(Phinci|/php|php/)i)
What regex should be used to identify PHP Riap clients. Riap clients often (should) send
ua
key identifying itself, e.g.Phinci/20130308.1
,Perinci/0.12
, etc.deconfuse_php_clients => BOOL (default: 1)
Whether to do special handling for PHP Riap clients (identified by
php_clients_ua_re
). PHP clients often confuse empty array[]
with empty hash{}
, since both areArray()
in PHP. If this setting is turned on, the server makes sureargs
becomes{}
when client sends[]
, and{}
arguments become[]
or vice versa according to hint provided by function metadata.
HOMEPAGE
Please visit the project's homepage at https://metacpan.org/release/Perinci-Access-HTTP-Server.
SOURCE
Source repository is at https://github.com/sharyanto/perl-Perinci-Access-HTTP-Server.
BUGS
Please report any bugs or feature requests on the bugtracker website https://rt.cpan.org/Public/Dist/Display.html?Name=Perinci-Access-HTTP-Server
When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.
SEE ALSO
AUTHOR
perlancar <perlancar@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2017, 2015, 2014, 2013, 2012, 2011 by perlancar@cpan.org.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.