Dancer2

 view release on metacpan or  search on metacpan

lib/Dancer2/Core/Request.pm  view on Meta::CPAN

package Dancer2::Core::Request;
# ABSTRACT: Interface for accessing incoming requests
$Dancer2::Core::Request::VERSION = '2.1.0';
use strict;
use warnings;
use parent 'Plack::Request';

use Carp;
use Encode qw(decode FB_CROAK LEAVE_SRC);
use URI;
use URI::Escape;
use Safe::Isa;
use Hash::MultiValue;
use Ref::Util qw< is_ref is_arrayref is_hashref is_coderef >;

use Dancer2::Core::Types;
use Dancer2::Core::Request::Upload;
use Dancer2::Core::Cookie;

# add an attribute for each HTTP_* variables
# (HOST is managed manually)
my @http_env_keys = (qw/
    accept_charset
    accept_encoding
    accept_language
    connection
    keep_alive
    x_requested_with
/);

# apparently you can't eval core functions
sub accept { $_[0]->env->{'HTTP_ACCEPT'} }

eval << "_EVAL" or die $@ for @http_env_keys; ## no critic
sub $_ { \$_[0]->env->{ 'HTTP_' . ( uc "$_" ) } }
1;
_EVAL

eval {
    require Unicode::UTF8;
    no warnings qw<redefine once>;
    *__decode = sub { Unicode::UTF8::decode_utf8($_[0]) };
    *__valid  = sub { Unicode::UTF8::valid_utf8($_[0]) };
    1;
} or do {
    no warnings qw<redefine once>;
    *__decode = sub { decode( 'UTF-8', $_[0] ) };
    *__valid  = sub {
        eval { decode( 'UTF-8', $_[0], FB_CROAK | LEAVE_SRC ); 1 };
    };
};

# check presence of XS module to speedup request
our $XS_URL_DECODE         = eval { require URL::Encode::XS; 1; };
our $XS_PARSE_QUERY_STRING = eval { require CGI::Deurl::XS;  1; };
our $XS_HTTP_COOKIES       = eval { require HTTP::XSCookies; 1; };

our $_id = 0;

# self->new( env => {}, serializer => $s, is_behind_proxy => 0|1 )
sub new {
    my ( $class, @args ) = @_;

    # even sized list
    @args % 2 == 0
        or croak 'Must provide even sized list';

    my %opts = @args;
    my $env  = $opts{'env'};

    my $self = $class->SUPER::new($env);

    if ( my $s = $opts{'serializer'} ) {
        $s->$_does('Dancer2::Core::Role::Serializer')
            or croak 'Serializer provided not a Serializer object';

        $self->{'serializer'} = $s;
    }

    # additionally supported attributes
    $self->{'id'}              = ++$_id;
    $self->{'vars'}            = {};
    $self->{'is_behind_proxy'} = !!$opts{'is_behind_proxy'};
    $self->{'uri_for_route'}   = $opts{'uri_for_route'};

    $opts{'body_params'}
        and $self->{'_body_params'} = $opts{'body_params'};

lib/Dancer2/Core/Request.pm  view on Meta::CPAN

=over 4

=item C<accept>

HTTP header: C<HTTP_ACCEPT>.

=item C<accept_charset>

HTTP header: C<HTTP_ACCEPT_CHARSET>.

=item C<accept_encoding>

HTTP header: C<HTTP_ACCEPT_ENCODING>.

=item C<accept_language>

HTTP header: C<HTTP_ACCEPT_LANGUAGE>.

=item C<agent>

Alias for C<user_agent>) below.

=item C<connection>

HTTP header: C<HTTP_CONNECTION>.

=item C<content_encoding>

HTTP header: C<HTTP_CONTENT_ENCODING>.

=item C<content_length>

HTTP header: C<HTTP_CONTENT_LENGTH>.

=item C<content_type>

HTTP header: C<HTTP_CONTENT_TYPE>.

=item C<forwarded_for_address>

HTTP header: C<HTTP_X_FORWARDED_FOR>.

=item C<forwarded_host>

HTTP header: C<HTTP_X_FORWARDED_HOST>.

=item C<forwarded_protocol>

One of either C<HTTP_X_FORWARDED_PROTOCOL>, C<HTTP_X_FORWARDED_PROTO>, or
C<HTTP_FORWARDED_PROTO>.

=item C<host>

Checks whether we are behind a proxy using the C<behind_proxy>
configuration option, and if so returns the first
C<HTTP_X_FORWARDED_HOST>, since this is a comma separated list.

If you have not configured that you are behind a proxy, it returns HTTP
header C<HTTP_HOST>.

=item C<keep_alive>

HTTP header: C<HTTP_KEEP_ALIVE>.

=item C<referer>

HTTP header: C<HTTP_REFERER>.

=item C<user_agent>

HTTP header: C<HTTP_USER_AGENT>.

=item C<x_requested_with>

HTTP header: C<HTTP_X_REQUESTED_WITH>.

=back

=head1 Fetching only params from a given source

If a required source isn't specified, a mixed hashref (or list of key value
pairs, in list context) will be returned; this will contain params from all
sources (route, query, body).

In practical terms, this means that if the param C<foo> is passed both on the
querystring and in a POST body, you can only access one of them.

If you want to see only params from a given source, you can say so by passing
the C<$source> param to C<params()>:

    my %querystring_params = params('query');
    my %route_params       = params('route');
    my %post_params        = params('body');

If source equals C<route>, then only params parsed from the route pattern
are returned.

If source equals C<query>, then only params parsed from the query string are
returned.

If source equals C<body>, then only params sent in the request body will be
returned.

If another value is given for C<$source>, then an exception is triggered.

=head1 EXTRA SPEED

If L<Dancer2::Core::Request> detects the following modules as installed,
it will use them to speed things up:

=over 4

=item * L<URL::Encode::XS>

=item * L<CGI::Deurl::XS>

=back

=head1 AUTHOR

Dancer Core Developers



( run in 0.545 second using v1.01-cache-2.11-cpan-39bf76dae61 )