MVC::Neaf::Request - Request class for Not Even A Framework
This is what your MVC::Neaf application is going to get as its ONLY input.
Here's a brief overview of what a Neaf request returns:
# How the application was configured: MVC::Neaf->route( "/matching/route" => sub { my $req = shift; ... }, path_info_regex => '.*' ); # What was requested: http(s)://server.name:1337/mathing/route/some/more/slashes?foo=1&bar=2 # What is being returned: $req->http_version = HTTP/1.0 or HTTP/1.1 $req->scheme = http or https $req->method = GET $req->hostname = server.name $req->port = 1337 $req->path = /mathing/route/some/more/slashes $req->prefix = /mathing/route $req->postfix = some/more/slashes # params and cookies require a regex $req->param( foo => '\d+' ) = 1
The actual Request object the application gets is going to be a subclass of this. Thus it is expected to have the following methods.
MVC::Neaf::Request->new( %arguments )
The application is not supposed to make its own requests, so this constructor is really for testing purposes only.
For now, just swallows whatever is given to it. Restrictions MAY BE added in the future though.
Returns the IP of the client. If X-Forwarded-For header is set, returns that instead.
X-Forwarded-For
Returns version number of http protocol.
http
Returns http or https, depending on how the request was done.
https
Returns true if https is used, false otherwise.
Return the HTTP method being used. GET is the default value if cannot determine (useful for command-line debugging).
HTTP
GET
Alias for $self->method eq 'POST'. May be useful in form submission, as in
$self->method eq 'POST'
$form = $request->form( $validator ); if ($request->is_post and $form->is_valid) { # save & redirect }; # show form again
Returns the hostname that was requested, or localhost if cannot detect.
localhost
Returns the port number.
Returns the path part of the URI. Path is guaranteed to start with a slash.
A MVC::Neaf::Route object that this request is being dispatched to.
If request is not inside an application, returns a MVC::Neaf::Route::Null instead.
$req->set_path( $new_path )
Set path() to new value. This may be useful in pre_route hook.
pre_route
Path will be canonized.
If no argument given, or it is undef, resets path() value to underlying driver's do_get_path.
undef
do_get_path
Returns self.
The part of the request that matched the route to the application being executed.
Guaranteed to start with slash. Unless set_path was called, it is a prefix of path().
set_path
path()
Not available before routing was applied to request.
Get scheme, server, and port of the application.
[EXPERIMENTAL] Name and meaning subject to change.
$req->get_url_rel( %override )
Produce a relative link to the page being served, possibly overriding some parameters.
Parameter order is NOT preserved. If parameter is empty or undef, it is skipped.
[CAUTION] Multiple values are ignored, this MAY change in the future.
[CAUTION] For a POST request, normal parameters are used instead of URL parameters (see url_param). This MAY change in the future.
url_param
$req->get_url_full( %override )
Same as above, but prefixed with schema, server name, and port.
Returns the part of URI path beyond what matched the application's path.
Contrary to the CGI specification, the leading slash is REMOVED.
The validation regex for this value MUST be specified during application setup as path_info_regex. See route in MVC::Neaf.
path_info_regex
route
[EXPERIMENTAL] This part of API is undergoing changes.
Return a list of matched capture groups found in path_info_regex, if any.
$req->set_path_info( $path_info )
Sets path_info to new value.
Also updates path() value so that path = script_name + path_info still holds.
$req->param( $name, $regex )
$req->param( $name, $regex, $default )
Return parameter, if it passes regex check, default value or undef otherwise.
The regular expression is applied to the WHOLE string, from beginning to end, not just the middle. Use '.*' if you really trust the data.
Dies if regular expression didn't match and the route has the strict flag.
strict
[EXPERIMENTAL] If param_regex hash was given during route definition, $regex MAY be omitted for params that were listed there. This feature is not stable yet, though. Use with care.
param_regex
$regex
If method other than GET/HEAD is being used, whatever is in the address line after ? is IGNORED. Use url_param (see below) if you intend to mix GET/POST parameters.
[NOTE] param() ALWAYS returns a single value, even in list context. Use multi_param() (see below) if you really want a list.
param()
multi_param()
[NOTE] param() has nothing to do with getting parameter list from request. Instead, use form with wildcards:
neaf form => "my_form" => [ [ 'guest\d+' => '.*'], [ 'arrival\d+' => '.*' ] ], engine => 'Wildcard'; # later in controller my $guests = $req->form("my_form"); $guests->fields; # has guest1 & arrival1, guest2 & arrival2 etc $guests->error; # hash with values that didn't match regex
See MVC::Neaf::X::Form::Wildcard.
$req->url_param( name => qr/regex/ )
If method is GET or HEAD, identical to param.
param
Otherwise would return the parameter from query string, AS IF it was a GET request.
Multiple values are deliberately ignored.
See CGI.
$req->multi_param( name => qr/regex/ )
Get a multiple value GET/POST parameter as a @list. The name generally follows that of newer CGI (4.08+).
@list
ALL values must match the regex, or an empty list is returned. Dies if strict mode if enabled for route and there is a mismatch.
[EXPERIMENTAL] This method's behavior MAY change in the future. Please be careful when upgrading.
$req->set_param( name => $value )
Override form parameter. Returns self.
$req->form( $validator )
Apply validator to raw params and return whatever it returns.
A validator MUST be an object with validate method, or a coderef, or a symbolic name registered earlier via neaf form ....
validate
neaf form ...
Neaf's own validators, MVC::Neaf::X::Form and MVC::Neaf::X::Form::LIVR, will return a MVC::Neaf::X::Form::Data object with the following methods:
MVC::Neaf::X::Form
MVC::Neaf::X::Form::LIVR
MVC::Neaf::X::Form::Data
is_valid - tells whether data passed validation
error - hash of errors, can also be modified if needed:
$result->error( myfield => "Correct, but not found in database" );
data - hash of valid, cleaned data
raw - hash of data entered initially, may be useful to display input form again.
You are encouraged to use this return format from your own validation class or propose improvements.
$req->get_form_as_list( qr/.../, qw(name1 name2 ...) )
$req->get_form_as_list( [ qr/.../, "default" ], qw(name1 name2 ...) )
Return a group of uniform parameters as a list, in that order. Values that fail validation are returned as undef, unless default given.
[EXPERIMENTAL] The name MAY be changed in the future.
See "body_raw" below.
Returns request body for PUT/POST requests as unicode text.
WARNING Encodings other than UTF-8 are not supported as of yet.
Get decoded request body in JSON format. In case of errors, error 422 is thrown.
Returns request body for PUT/POST requests as binary data. Decoding and validation is left up to the user.
$req->upload_utf8( "name" )
Returns an MVC::Neaf::Upload object corresponding to an uploaded file, if such uploaded file is present.
All data read from such upload will be converted to unicode, raising an exception if decoding ever fails.
An upload object has at least handle and content methods to work with data:
handle
content
my $upload = $req->upload("user_file"); if ($upload) { my $untrusted_filename = $upload->filename; my $fd = $upload->handle; while (<$fd>) { ... }; }
or just
if ($upload) { while ($upload->content =~ /(...)/g) { do_something($1); }; };
$req->upload_raw( "name" )
Like above, but no decoding whatsoever is performed.
$req->get_cookie( "name" => qr/regex/ [, "default" ] )
Fetch client cookie. The cookie MUST be sanitized by regular expression.
The regular expression is applied to the WHOLE string, from beginning to end, not just the middle. Use '.*' if you really need none.
$req->set_cookie( name => "value", %options )
Set HTTP cookie. %options may include:
%options
regex - regular expression to check outgoing value
regex
ttl - time to live in seconds. 0 means no ttl. Use negative ttl and empty value to delete cookie.
ttl
expire - UNIX time stamp when the cookie expires (overridden by ttl).
expire
expires - [DEPRECATED] - use 'expire' instead (without trailing "s")
expires
domain
path
httponly - flag
httponly
secure - flag
secure
$req->delete_cookie( "name" )
Remove cookie by setting value to an empty string, and expiration in the past. [NOTE] It is up to the user agent to actually remove cookie.
Converts stored cookies into an arrayref of scalars ready to be put into Set-Cookie header.
$req->error( status )
Report error to the CORE.
This throws an MVC::Neaf::Exception object.
MVC::Neaf::Exception
If you're planning calling $req->error within eval block, consider using neaf_err function to let it propagate:
$req->error
eval
neaf_err
use MVC::Neaf::Exception qw(neaf_err); eval { $req->error(422) if ($foo); $req->redirect( "http://google.com" ) if ($bar); }; if ($@) { neaf_err($@); # The rest of the catch block };
$req->redirect( $location )
Redirect to a new location.
This throws an MVC::Neaf::Exception object. See error() discussion above.
error()
header_in() - return headers as-is
header_in()
$req->header_in( "header_name", qr/.../ )
Fetch HTTP header sent by client. Header names are canonized, so Http-Header, HTTP_HEADER and http_header are all the same.
Http-Header
HTTP_HEADER
http_header
Without argument, returns a HTTP::Headers::Fast object.
With a name, returns all values for that header in list context, or ", " - joined value as one scalar in scalar context. An empty string is returned if no such header is present.
If regex fails to match any of the header values, error 422 is thrown.
This call still works without regex, but such behavior is deprecated.
Get/set HTTP referrer - i.e. where the request pretends to come from.
[NOTE] Avoid using this for anything serious/secure - too easy to forge.
Get/set user_agent.
[NOTE] Avoid using user_agent for anything serious - too easy to forge.
Returns Content-Type request header, if present, or an empty string.
Content-Type
The usage of Content-Type in GET/HEAD requests is discouraged. See also body.
Dump whatever came in the request. Useful for debugging.
Get reference to session data. This reference is guaranteed to be the same throughout the request lifetime.
If MVC::Neaf->set_session_handler() was called during application setup, this data will be initialized by that handler; otherwise initializes with an empty hash (or whatever session engine generates).
If session engine was not provided, dies instead.
See MVC::Neaf::X::Session for details about session engine internal API.
Like above, but don't create session - just fetch from cookies & storage.
Never tries to load anything if session already loaded or created.
$req->save_session( [$replace] )
Save whatever is in session data reference.
If argument is given, replace session (if any) altogether with that one before saving.
Remove session.
Typically, a Neaf user only needs to return a hashref with the whole reply to client.
However, sometimes more fine-grained control is required.
In this case, a number of methods help stashing your data (headers, cookies etc) in the request object until the response is sent.
Also some lengthly actions (e.g. writing request statistics or sending confirmation e-mail) may be postponed until the request is served.
$req->header_out( [$header_name] )
Without parameters returns a HTTP::Headers::Fast-compatible object containing all headers to be returned to client.
With one parameter returns this header.
Returned values are just proxied HTTP::Headers::Fast returns. It is generally advised to use them in list context as multiple headers may return trash in scalar context.
E.g.
my @old_value = $req->header_out( foobar => set => [ "XX", "XY" ] );
or
my $old_value = [ $req->header_out( foobar => delete => 1 ) ];
[NOTE] This format may change in the future.
$req->set_header( $name, $value || [] )
$req->push_header( $name, $value || [] )
$req->remove_header( $name )
Set, append, and delete values in the header_out object. See HTTP::Headers::Fast.
Arrayrefs are fine and will set multiple values for a given header.
Returns reply hashref that was returned by controller, if any. Returns undef unless the controller was actually called. This may be useful in postponed actions or hooks.
This is killed by a clear() call.
clear()
Stash (ah, the naming...) is a temporary set of data that only lives throughtout request's lifetime and never gets to the client.
This may be useful to maintain shared data across hooks and callbacks. Usage is as follows:
$req->stash() - get the whole stash as hash.
$req->stash()
$req->stash( "name" ) - get a single value
$req->stash( "name" )
$req->stash( %save_data ) - set multiple values, old data is overridden rather than replaced.
$req->stash( %save_data )
As a rule of thumb,
use session if you intend to share data between requests;
session
use reply if you intend to render the data for the user;
reply
use stash as a last resort for temporary, private data.
stash
Stash is not killed by clear() function so that cleanup hooks aren't botched accidentally.
$req->postpone( CODEREF->($request) )
$req->postpone( [ CODEREF->($request), ... ] )
Execute a function (or several) right after the request is served.
Can be called multiple times.
[CAVEAT] If CODEREF contains reference to the request, the request will never be destroyed due to circular reference. Thus CODEREF may not be executed.
Don't pass request to CODEREF, use my $req = shift instead.
my $req = shift
$req->write( $data )
Write data to client inside -continue callback, unless close was called.
-continue
close
Stop writing to client in -continue callback.
By default, does nothing, as the socket will probably be closed anyway when the request finishes.
Remove all data that belongs to reply. This is called when a handler bails out to avoid e.g. setting cookies in a failed request.
Fetch unique request id. If none has been set yet (see "set_id"), use "make_id" method to create one.
The request id is present in both log messages from Neaf and default error pages, making it easier to establish link between the two.
Custom ids can be provided, see "make_id" below.
$req->set_id( $new_value )
Set the id above to a user-supplied value.
If a false value given, just generate a new one next time id is requested.
Symbols outside ascii, as well as whitespace and " and C"\", are prohibited.
ascii
"
Returns the request object.
$req->log_error( $message )
Log an error message, annotated with request id and the route being processed.
Currently works via warn, but this may change in the future.
[EXPERIMENTAL] This feature is still under development.
One can count on log_error to be available in the future and do some king of logging.
log_error
NOT TO BE CALLED BY USER.
Execute postponed functions. This is called in DESTROY by default, but request driver may decide it knows better.
Flushes postponed queue. Ignores exceptions in functions being executed.
Generally Neaf allows to define custom Request methods restricted to certain path & method combinations.
The following methods are available by default, but can be overridden via the helper mechanism.
For instance,
use MVC::Neaf; my $id; neaf helper => make_id => sub { $$ . "_" . ++$id }; neaf helper => make_id => \&unique_secure_base64, path => '/admin';
Create unique request id, e.g. for logging context. This is called by "id" if the id has not yet been set.
By default, generates MD5 checksum based on time, hostname, process id, and a sequential number and encodes as URL-friendly base64.
[CAUTION] This should be unique, but may not be secure. Use MVC::Neaf::X::Session if you need something to rely upon.
$req->log_message( $level => $message );
By default would print uppercased level, $request->id, route, and the message itself.
Levels are not restricted whatsoever. Suggested values are "fatal", "error", "warn", "debug".
The following methods MUST be implemented in every Request subclass to create a working Neaf backend.
They SHOULD NOT be called directly inside the application.
do_get_client_ip()
do_get_http_version()
do_get_method()
do_get_scheme()
do_get_hostname()
do_get_port()
do_get_path()
do_get_params()
do_get_param_as_array() - get single GET/POST parameter in list context
do_get_upload()
do_get_body()
do_get_header_in() - returns a HTTP::Headers-compatible object.
do_reply( $status, $content ) - write reply to client
do_reply( $status ) - only send headers to client
do_write( $data )
do_close()
Some methods become obsolete during Neaf development. Anything that is considered deprecated will continue to be supported for at least three minor versions after official deprecation and a corresponding warning being added.
Please keep an eye on Changes though.
Changes
Here are these methods, for the sake of completeness.
See "prefix"
See "postfix".
These three will start warning in 0.30 and will be removed in 0.40
Return all keys in header_in object as a list.
[DEPRECATED] Use $req->header_in->header_field_names instead.
$req->header_in->header_field_names
Returns file:line where controller was defined.
[DEPRECATED] This function was added prematurely and shall not be used.
$req->get_form_as_hash( name => qr/.../, name2 => qr/..../, ... )
[DEPRECATED] and dies. Use MVC::Neaf::X::Form instead.
$req->set_default( key => $value, ... )
As of v.0.20 this dies.
Use path-based defaults, or stash().
This module is part of MVC::Neaf suite.
Copyright 2016-2019 Konstantin S. Uvarin khedin@cpan.org.
khedin@cpan.org
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
To install MVC::Neaf, copy and paste the appropriate command in to your terminal.
cpanm
cpanm MVC::Neaf
CPAN shell
perl -MCPAN -e shell install MVC::Neaf
For more information on module installation, please visit the detailed CPAN module installation guide.