NAME
Kelp::Request - Request class for a Kelp application
SYNOPSIS
my $request = Kelp::Request( app => $app, env => $env );
DESCRIPTION
This module provides a convenience layer on top of Plack::Request. It extends it to add several convenience methods and support for application encoding.
ENCODING
Starting with version 2.10, Kelp::Request simplifies input handling and improves correctness by automatically decoding path, query parameters and content.
Headers (so cookies as well) are unaffected, as they aren't consistently supported outside of ASCII range. JSON now decodes request data into the proper charset instead of flat utf8 regardless of configuration. Sessions are configured separately in middlewares, so they must themselves do the proper decoding.
Following methods will return values decoded with charset either from Content-Type
header or the one specified in the app's configuration ("request_charset" in Kelp):
param
cgi_param
body_param
json_param
parameters
body_parameters
content
json_content
Following methods will always decode to "request_charset" in Kelp because they are not the part of message's content (URIs should always be in ASCII-compilant encoding, UTF-8 is preferable):
path
param
(from query)cgi_param
(from query)parameters
(from query)query_parameters
If you wish to get input in the original request encoding, use these instead (note: there is no raw_param
):
raw_path
raw_parameters
raw_query_parameters
raw_body_parameters
raw_body
(instead ofcontent
)
Following methods will return decoded values if the other parts of the system are configured to decode them:
session
- depends on session middleware
Some caveats about the automatic decoding and "request_charset" in Kelp configuration parameter:
As always, UTF-8 (the default) works best - don't change to avoid issues. Other ASCII-compilant encodings should work well. "content" will always be decoded properly, but application/x-www-form-urlencoded
and multipart/form-data
will have issues with non-ASCII-compilant encodings. Especially the latter, because the information about Content-Type
of a single part is lost on Plack level and it is not properly decoded using that encoding. In such corner cases, you should probably get the full undecoded body using "raw_body" and parse it yourself.
If you wish to disable automatic decoding, you can set "request_charset" in Kelp to undef - it will then ignore any charset which came with the message and let you do your own decoding.
ATTRIBUTES
app
A reference to the Kelp application. This will always be the real application, not the reblessed controller.
stash
Returns a hashref, which represents the stash of the current the request
An all use, utility hash to use to pass information between routes. The stash is a concept originally conceived by the developers of Catalyst. It's a hash that you can use to pass data from one route to another.
# put value into stash
$self->req->stash->{username} = app->authenticate();
# more convenient way
$self->stash->{username} = app->authenticate();
# get value from stash
return "Hello " . $self->req->stash->{username};
# more convenient way
return "Hello " . $self->stash('username');
named
This hash is initialized with the named placeholders of the path that the current route is processing.
route_name
Contains a string name of the route matched for this request. Contains route pattern if the route was not named.
charset
Returns the charset from the Content-Type
HTTP header or undef
if there is none. Will ignore the charset unless Content-Type
is text/*
or application/*
. Readonly.
METHODS
param
Shortcut for returning the HTTP parameters of the request with heavy amount of dwimmery. It has two modes of operation and behaves differently for JSON and non-JSON requests.
If passed with a parameter, returns the value value of a parameter with that name from either request body or query (body is preferred). This always returns a scalar value.
If passed without parameters, returns the list containing the names of available parameters. This always returns a list.
The behavior is changed when the content type of the request is application/json
and a JSON module is loaded. In that case, it will decode the JSON body and return values from it instead. If the root contents of the JSON document is not an HASH
(after decoding), then it will be wrapped into a hash with its reftype as a key, for example:
{ ARRAY => [...] } # when JSON contains an array as root element
{ '' => [...] } # when JSON contains something that's not a reference
my $array_ref = $kelp->param('ARRAY');
There also exists a special, deprecated behavior of param
returning the entire contents of json when called without arguments in scalar context. This will be later removed, so that param
will work exactly the same regardless of whether the request was json. Use "json_content" for that instead.
Since this method behaves differently based on the form of input, you're encouraged to use other, more specific methods listed below.
query_param
Same as "param", but always returns parameters from query string.
body_param
Same as "param", but always returns parameters from body form.
json_param
Same as "param", but always returns parameters from JSON body.
cgi_param
CGI.pm compatible implementation of param
(but does not set parameters). It is not recommended to use this method, unless for some reason you have to maintain CGI.pm compatibility. Misusing this method can lead to bugs and security vulnerabilities.
parameters
Same as "parameters" in Plack::Request, but the keys and values in the hash are decoded.
raw_parameters
Same as "parameters" in Plack::Request. The hash keys and values are not decoded.
query_parameters
Same as "query_parameters" in Plack::Request, but the keys and values in the hash are decoded.
raw_query_parameters
Same as "query_parameters" in Plack::Request, The hash keys and values are not decoded.
body_parameters
Same as "body_parameters" in Plack::Request, but the keys and values in the hash are decoded.
raw_body_parameters
Same as "body_parameters" in Plack::Request, The hash keys and values are not decoded.
content
Same as "content" in Plack::Request, but the result is decoded.
This is the go-to method for getting the request body for string manipulation character by character. It can be useful when you, for example, want to run a regex on the body. Use this instead of "raw_body".
raw_body
Same as "raw_body" in Plack::Request. The result is not decoded.
This is the go-to method for getting the request body for string manipulation byte by byte. An example would be deserializing the body with a custom serializer. Use this instead of "content".
json_content
Returns the json-decoded body of the request or undef if the request is not json, there is no json decoder or an error occured.
path
Same as "path" in Plack::Request, but the result is decoded.
raw_path
Same as "path" in Plack::Request. The result is not decoded.
address, remote_host, user
These are shortcuts to the REMOTE_ADDR, REMOTE_HOST and REMOTE_USER environment variables.
if ( $self->req->address eq '127.0.0.1' ) {
...
}
Note: See "Deploying" in Kelp::Cookbook for configuration required for these fields when using a proxy.
session
Returns the Plack session hash or croaks if no Session
middleware was included.
sub get_session_value {
my $self = shift;
$self->session->{user} = 45;
}
If called with a single argument, returns that value from the session hash:
sub set_session_value {
my $self = shift;
my $user = $self->req->session('user');
# Same as $self->req->session->{'user'};
}
Set values in the session using key-value pairs:
sub set_session_hash {
my $self = shift;
$self->req->session(
name => 'Jill Andrews',
age => 24,
email => 'jill@perlkelp.com'
);
}
Replace all values with a hash:
sub set_session_hashref {
my $self = shift;
$self->req->session( { bar => 'foo' } );
}
Clear the session:
sub clear_session {
my $self = shift;
$self->req->session( {} );
}
Delete session value:
delete $self->req->session->{'useless'};
is_ajax
Returns true if the request was called with XMLHttpRequest
.
content_type_is
Returns true if request has a Content-Type
header starting with a passed string.
is_text
Returns true if the request's content type was text/plain
.
is_html
Returns true if the request's content type was text/html
.
is_json
Returns true if the request's content type was application/json
.
is_xml
Returns true if the request's content type was application/xml
.
charset_decode
Shortcut method, which decodes a string using "charset" or "request_charset" in Kelp. A second optional parameter can be passed, and if true will cause the method to ignore charset passed in the Content-Type
header.
It does noting if "request_charset" in Kelp is undef or false.