Dancer2...Request(3)

🌸 Dancer2::Core::Request 🌸

okay so bestie, this page is all about Dancer2::Core::Request β€” straight out of the User Contributed Perl Documentation crowd. Buckle up, it's giving main character energy for every request that hits your app. πŸ’…

NAME

Dancer2::Core::Request β€” Interface for accessing incoming requests

VERSION

version 2.2.1 ✨

SYNOPSIS

Inside a route handler, the current request object pulls up through the request keyword, like:

get '/foo' => sub {
    request->params; # request, params parsed as a hash ref
    request->body;   # returns the request body, unparsed
    request->path;   # the path requested by the client
    # ...
};

DESCRIPTION

It's an object representing a Dancer2 request, and its whole purpose is to hand you a proper interface to literally anything you could possibly need from a web request. Obsessed. πŸ¦‹


METHODS πŸŽ€

address

Returns the IP address of the client. πŸ“

base

Returns an absolute URI for the base of the application. You get a URI object back (which stringifies to the URL, exactly as you'd expect). ✨

body_parameters

Returns a Hash::MultiValue object representing the POST parameters.

body

Returns the raw body of the request, unparsed.

If you need to access the body of the request, you have to use this accessor and you should not try to read psgi.input by hand. Dancer2::Core::Request already did it for you and kept the raw body untouched in there. πŸ™ˆ

body_data

Returns the body of the request in data form, which makes it possible to tell the difference between body_parameters β€” a representation of the request parameters (Hash::MultiValue) β€” and other forms of content.

If a serializer is set, this is the deserialized request body. Otherwise this is the decoded body parameters (if any), or the body content itself.

content

Returns the undecoded byte string POST body.

cookies

Returns a reference to a hash containing cookies, where the keys are the names of the cookies and the values are Dancer2::Core::Cookie objects. πŸͺ

data

If the application has a serializer and if the request has serialized content, returns the deserialized structure as a hashref.

dispatch_path

Alias for path. Deprecated. πŸ‘€ (like, still works, but don't build your whole personality on it)

env

Return the current PSGI environment hash reference.

header($name)

Return the value of the given header, if present. If the header has multiple values, returns the list of values when called in list context, and the first one in scalar. 🌈

headers

Returns either an HTTP::Headers or an HTTP::Headers::Fast object representing the headers.

id

The ID of the request. This lets you trace a specific request in loggers, per the string created using to_string.

The ID of the request is essentially the number of requests run in the current class.

input

Alias to the input_handle method below.

input_handle

Alias to the PSGI input handle (request->env->{'psgi.input'})

is_ajax

Return true if the value of the header X-Requested-With is XMLHttpRequest.

is_delete

Return true if the method requested by the client is 'DELETE'

is_get

Return true if the method requested by the client is 'GET'

is_head

Return true if the method requested by the client is 'HEAD'

is_post

Return true if the method requested by the client is 'POST'

is_put

Return true if the method requested by the client is 'PUT'

is_options

Return true if the method requested by the client is 'OPTIONS'

logger

Returns the psgix.logger code reference, if it exists.

method

Return the HTTP method used by the client to access the application.

So here's the tea: while this method returns the method string exactly as the environment provides it, it's way better to use one of the boolean accessors below if you want to inspect the requested method. πŸ’…

new

The constructor of the class, used internally by Dancer2's core to create request objects.

It uses the environment hash table you give it to build the request object:

Dancer2::Core::Request->new( env => $env );

There are two extra parameters for instantiation:

  • serializer

A serializer object to work with when reading the request body.

  • body_params

Provide body parameters.

Used internally when we need to avoid parsing the body again.

param($key)

Calls the params method below and fetches the key you provided.

params($source)

Called in scalar context, it returns a hashref of params β€” either from the source you specified (more on that below) or merging all the sources together.

So you can do, for instance:

my $foo = params->{foo}

If it's called in list context, it returns a list of key and value pairs, so you could do:

my %allparams = params;

Parameters are merged in the following order: query, body, route β€” i.e. route parameters have the highest priority:

POST /hello/Ruth?name=Quentin

name=Bobbie

post '/hello/:name' => sub {
    return "Hello, " . route_parameters->get('name') . "!"; # returns Ruth
    return "Hello, " . query_parameters->get('name') . "!"; # returns Quentin
    return "Hello, " . body_parameters->get('name') . "!";  # returns Bobbie
    return "Hello, " . param('name') . "!";                 # returns Ruth
};

The query_parameters, route_parameters, and body_parameters keywords each provide a Hash::MultiValue result from the three different parameters. We highly recommend using these instead of params, because of the potential for unintentional behaviour β€” consider the following request and route handler:

POST /artist/104/new-song

name=Careless Dancing

post '/artist/:id/new-song' => sub {
  find_artist(param('id'))->create_song(params);
  # oops! we just passed id into create_song,
  # but we probably only intended to pass name
  find_artist(param('id'))->create_song(body_parameters);
};
POST /artist/104/join-band

id=4
name=Dancing Misfits

post '/artist/:id/new-song' => sub {
  find_artist(param('id'))->join_band(params);
  # oops! we just passed an id of 104 into join_band,
  # but we probably should have passed an id of 4
};
bestie, the way those two "oops!" moments sneak up on you… that's exactly the vibe check params fails. 😭

parameters

Returns a Hash::MultiValue object with merged GET and POST parameters.

Parameters are merged in the following order: query, body, route β€” i.e. route parameters have the highest priority β€” see params for how this works, and the associated risks and alternatives. 🫢

path

The decoded path requested by the client, normalized. This is effectively path_info, or a single forward /. Invalid UTF-8 is left as bytes in lenient mode (with a warning), or throws an error in strict UTF-8 mode.

path_info

The raw requested path. This could be empty. Use path instead. πŸ™ˆ

port

Return the port of the server.

protocol

Return the protocol (HTTP/1.0 or HTTP/1.1) used for the request.

query_parameters

Returns a Hash::MultiValue parameters object.

query_string

Returns the portion of the request defining the query itself β€” this is what comes after the ? in a URI.

raw_body

Alias to the content method.

remote_address

Alias for the address method.

remote_host

Return the remote host of the client. This only works with web servers configured to do a reverse DNS lookup on the client's IP address.

request_method

Alias to the method accessor, for backward-compatibility with the CGI interface.

request_uri

Return the raw, undecoded request URI path.

route

Return the route which this request matched.

scheme

Return the scheme of the request

script_name

Return script_name from the environment.

secure

Return true or false, indicating whether the connection is secure β€” this is effectively checking if the scheme is HTTPS or not. πŸ”’

serializer

Returns the optional serializer object used to deserialize request parameters.

session

Returns the psgix.session hash, if it exists.

session_options

Returns the psgix.session.options hash, if it exists.

to_string

Return a string representing the request object (e.g., GET /some/path).

upload($name)

Context-aware accessor for uploads. It's a wrapper around an access to the hash table provided by uploads(). It looks at the calling context and returns the corresponding value.

If you have many file uploads under the same name, and you call upload('name') in an array context, the accessor will unroll the ARRAY ref for you:

my @uploads = request->upload('many_uploads'); # OK

Whereas if you manually access the hash table, you'll end up with one element in @uploads, being the arrayref:

my @uploads = request->uploads->{'many_uploads'};
# $uploads[0]: ARRAY(0xXXXXX)

That is exactly why you should use this accessor instead of a manual access to uploads. 🧚

uploads

Returns a reference to a hash containing uploads. Values can be either a Dancer2::Core::Request::Upload object, or an arrayref of Dancer2::Core::Request::Upload objects.

You should probably use the upload($name) accessor instead of manually accessing the uploads hash table.

uri

An alias to request_uri.

uri_base

Same thing as base above, except it removes the last trailing slash in the path if it is the only path.

This means that if your base is http://myserver/, uri_base will return http://myserver (notice: no trailing slash). This is considered very useful when using templates to do the following thing:

<link rel="stylesheet" href="[% request.uri_base %]/css/style.css" />

uri_for(path, params)

Constructs a URI from the base and the passed path. If params (a hashref) is supplied, these get added to the query string of the URI.

So, with the following base:

http://localhost:5000/foo

You get the following behavior:

my $uri = request->uri_for('/bar', { baz => 'baz' });
print $uri; # http://localhost:5000/foo/bar?baz=baz

uri_for returns a URI object (which can stringify to the value). ✨

uri_for_route(route_name, route_params, query_params, escape)

Constructs a URI from the base and the path of the specified route name.

Read more about it in the Dancer2::Manual::Keywords document under uri_for_route.

user

Return remote user if defined.

var

By-name interface to variables stored in this request object.

  my $stored = $request->var('some_variable');

returns the value of 'some_variable', while

  $request->var('some_variable' => 'value');

will set it.

vars

Access to the internal hash of variables:

    my $value = $request->vars->{'my_key'};

You want to use var above instead. πŸ’–

okay bestie, the glow-up continues πŸ’… you already know the main methods, so now let's talk about the cute little shortcuts for peeking at what the client sent us. Commonly used client-supplied HTTP request headers each get their very own accessor, and yes, they're all serving exactly what it says on the tin ✨

  • accept β€” the HTTP_ACCEPT header πŸŽ€
  • accept_charset β€” the HTTP_ACCEPT_CHARSET header
  • accept_encoding β€” the HTTP_ACCEPT_ENCODING header
  • accept_language β€” the HTTP_ACCEPT_LANGUAGE header
  • agent β€” literally just an alias for user_agent (scroll down, it's there) πŸ‘‡
  • connection β€” the HTTP_CONNECTION header
  • content_encoding β€” the HTTP_CONTENT_ENCODING header
  • content_length β€” the HTTP_CONTENT_LENGTH header
  • content_type β€” the HTTP_CONTENT_TYPE header
  • forwarded_for_address β€” the HTTP_X_FORWARDED_FOR header
  • forwarded_host β€” the HTTP_X_FORWARDED_HOST header
  • forwarded_protocol β€” whichever of these three exists: HTTP_X_FORWARDED_PROTOCOL, HTTP_X_FORWARDED_PROTO, or HTTP_FORWARDED_PROTO πŸ¦‹
  • host β€” okay this one has lore. It checks the behind_proxy configuration option to see if you're sitting behind a proxy, and if you are, it hands back the first HTTP_X_FORWARDED_HOST β€” because that header is a comma separated list, babes, not a single value. If you haven't told it you're behind a proxy, it just returns the plain old HTTP_HOST header. no cap.
  • keep_alive β€” the HTTP_KEEP_ALIVE header
  • referer β€” the HTTP_REFERER header (yes spelled like that, we don't make the rules)
  • user_agent β€” the HTTP_USER_AGENT header
  • x_requested_with β€” the HTTP_X_REQUESTED_WITH header

🌸 Fetching only params from a given source 🌸

So here's the tea πŸ“ if you don't tell it which source you want, you get back a mixed hashref β€” or a list of key/value pairs if you're in list context β€” and that thing is a whole mashup of params from every source: route, query, and body. all three, blended, smoothie style 🧚

Which is lowkey a problem in practice, bestie: if the param foo gets passed both on the querystring and in a POST body, you can only reach one of them. 😭 the other one is just... sitting there. invisible. iconic but unhelpful.

So if you want params from one specific source only, just say so β€” pass the $source param into params():

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

and here's what each one actually gives you ✨

  • if source equals route, you get only the params parsed from the route pattern
  • if source equals query, you get only the params parsed from the query string
  • if source equals body, you get only the params sent in the request body
and if you pass literally anything else as $source? 🚨 an exception gets triggered. periodt. no gentle fallback, no vibes-based guessing.

πŸ”₯ EXTRA SPEED πŸ”₯

okay so this is the part where things get fast πŸ’¨ if Dancer2::Core::Request spots the following modules chilling in your installed modules, it's gonna use them to speed everything up:

  • URL::Encode::XS
  • CGI::Deurl::XS

that's it. that's the whole trick. free performance if you happen to have them, no config needed πŸ‘‘


πŸ‘‘ AUTHOR πŸ‘‘

Dancer Core Developers


This software is copyright (c) 2026 by Alexis Sukrieh.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. 🫢


and that's a wrap, bestie!! this page came to you courtesy of perl v5.42.3, dated 2026-09-20 β€” go forth and parse those headers, you absolute legend β­πŸŒˆπŸ’œ

πŸ“¦ where this page comes from