request

Request

MVC::Keayl::Request is a read-only wrapper around a single incoming HTTP request. The server adapter builds one per request from the raw method, target, headers, body, connection scheme, and peer address; controllers and middleware then read from it through a small, stable accessor surface.

use MVC::Keayl::Request;

my $request = MVC::Keayl::Request.new(
  :method<POST>,
  :target('/users?role=admin'),
  :headers({ Host => 'example.com:3000', 'Content-Type' => 'application/json' }),
  :scheme<https>,
  :remote-address('203.0.113.5'),
  :body('{"name":"Ada"}'),
);

Construction

Named argumentMeaning
:methodHTTP verb; normalized to uppercase. Defaults to GET.
:targetRaw request target (path?query); split into path and query-string.
:pathPath, when not supplying :target. Defaults to /.
:query-stringQuery string, when not supplying :target. Defaults to empty.
:headersA hash of header names to values; names are matched case-insensitively.
:schemeConnection scheme (http / https); normalized to lowercase.
:remote-addressThe peer address reported by the connection.
:bodyThe request body: a Str, a Blob, or a Callable read lazily.

Supplying :target takes precedence over :path / :query-string.

Method and verb predicates

method returns the normalized verb. Each predicate is an exact match:

$request.method;      # 'POST'

$request.is-get;      # False
$request.is-post;     # True
$request.is-put;
$request.is-patch;
$request.is-delete;
$request.is-head;

Path and query string

$request.path;          # '/users'
$request.query-string;  # 'role=admin'

query-params parses the query string on first access (and memoizes it). Values are percent- and plus-decoded, and repeated keys collect into an ordered array:

# /search?q=a%20b&tag=x&tag=y
$request.query-params;     # { q => 'a b', tag => ['x', 'y'] }

Headers

Header lookups are case-insensitive, and multi-value headers are joined with , :

$request.header('content-type');   # 'application/json'
$request.has-header('Host');       # True
$request.has-header('x-missing');  # False

is-xhr reports an AJAX request (X-Requested-With: XMLHttpRequest):

$request.is-xhr;   # True when the header is present

Scheme, host, port, and SSL

These derive from the connection and from proxy headers, so they are correct behind a reverse proxy:

$request.scheme;     # 'https'  (X-Forwarded-Proto overrides the connection scheme)
$request.is-ssl;     # True when the scheme is https

$request.host;       # 'example.com'  (X-Forwarded-Host overrides Host; port stripped)
$request.port;       # 3000

port is resolved in order: an explicit port on the host header, then X-Forwarded-Port, then the scheme default (443 for https, 80 for http).

Remote IP

remote-ip prefers the first entry of X-Forwarded-For (the originating client) and falls back to the connection's peer address:

# X-Forwarded-For: 203.0.113.5, 10.0.0.1
$request.remote-ip;   # '203.0.113.5'

Body

The body is read lazily. A Callable source is invoked only on the first call to body, and the result is memoized. A Blob is decoded as UTF-8, and a missing body reads as the empty string:

$request.body;   # '{"name":"Ada"}'

Reading the raw body never consumes or parses it. Structured parameter parsing (form bodies, JSON, multipart) is layered on top by the controller.

body-blob returns the raw body as an undecoded Blob. Multipart uploads carry binary file data that is not valid UTF-8, so parsing them starts from these bytes rather than from body:

$request.body-blob;   # Blob of the raw request bytes

Variant

A variant marks a device-specific view selection. It is undefined until set, and set-variant assigns it:

$request.set-variant('phone');
$request.variant;   # 'phone'

detect-variant reads the User-Agent header and returns phone for a mobile agent, tablet for an iPad-style agent, or an undefined value otherwise. Wire it in by hand when a variant should follow the device:

$request.set-variant($request.detect-variant);

The controller uses the variant to branch respond-to blocks and to prefer a variant template such as show.html+phone.haml.

MVC::Keayl v0.9.1

Model-View-Controller web framework

Authors

  • Greg Donald

License

Artistic-2.0

Dependencies

Cro::HTTPCrypt::RandomDigest::HMACDigest::SHA1::NativeOpenSSLMIME::Base64YAMLishORM::ActiveRecord:auth<zef:gdonald>Template::HAML:auth<zef:gdonald>

Provides

  • MVC::Keayl
  • MVC::Keayl::APIController
  • MVC::Keayl::ActionText
  • MVC::Keayl::ActionText::Repository
  • MVC::Keayl::ActionText::RichTextable
  • MVC::Keayl::Adapter
  • MVC::Keayl::Adapter::Cro
  • MVC::Keayl::Adapter::Test
  • MVC::Keayl::Application
  • MVC::Keayl::Assets
  • MVC::Keayl::Assets::Serving
  • MVC::Keayl::CLI
  • MVC::Keayl::CSRF
  • MVC::Keayl::Cable::Broadcasting
  • MVC::Keayl::Cable::Channel
  • MVC::Keayl::Cable::Connection
  • MVC::Keayl::Cable::PubSub
  • MVC::Keayl::Cable::PubSub::External
  • MVC::Keayl::Cable::PubSub::InMemory
  • MVC::Keayl::Cache
  • MVC::Keayl::Caching
  • MVC::Keayl::Config
  • MVC::Keayl::Controller
  • MVC::Keayl::Cookies
  • MVC::Keayl::Credentials
  • MVC::Keayl::Dispatcher
  • MVC::Keayl::Endpoint
  • MVC::Keayl::Engine
  • MVC::Keayl::ErrorReporter
  • MVC::Keayl::ErrorReporting
  • MVC::Keayl::Errors
  • MVC::Keayl::ExceptionPage
  • MVC::Keayl::Flash
  • MVC::Keayl::HealthController
  • MVC::Keayl::Helpers::Asset
  • MVC::Keayl::Helpers::DateTime
  • MVC::Keayl::Helpers::Form
  • MVC::Keayl::Helpers::Number
  • MVC::Keayl::Helpers::Options
  • MVC::Keayl::Helpers::Tag
  • MVC::Keayl::Helpers::Text
  • MVC::Keayl::Helpers::Url
  • MVC::Keayl::HttpAuthentication
  • MVC::Keayl::I18n
  • MVC::Keayl::I18n::Locale
  • MVC::Keayl::I18n::Pluralization
  • MVC::Keayl::Job
  • MVC::Keayl::Job::GlobalID
  • MVC::Keayl::Job::QueueAdapter
  • MVC::Keayl::Job::QueueAdapter::Async
  • MVC::Keayl::Job::QueueAdapter::Database
  • MVC::Keayl::Job::QueueAdapter::Inline
  • MVC::Keayl::Job::QueueAdapter::Test
  • MVC::Keayl::Live
  • MVC::Keayl::LogEvent
  • MVC::Keayl::Logger
  • MVC::Keayl::Mail
  • MVC::Keayl::Mailbox
  • MVC::Keayl::Mailbox::Ingress
  • MVC::Keayl::Mailbox::Router
  • MVC::Keayl::Mailer
  • MVC::Keayl::Mailer::Delivery
  • MVC::Keayl::Mailer::Delivery::File
  • MVC::Keayl::Mailer::Delivery::SMTP
  • MVC::Keayl::Mailer::Delivery::Test
  • MVC::Keayl::Mailer::DeliveryJob
  • MVC::Keayl::Mailer::Preview
  • MVC::Keayl::Middleware
  • MVC::Keayl::Middleware::Database
  • MVC::Keayl::Middleware::HostAuthorization
  • MVC::Keayl::Middleware::Logger
  • MVC::Keayl::Middleware::RequestId
  • MVC::Keayl::Middleware::SSL
  • MVC::Keayl::Middleware::SecureHeaders
  • MVC::Keayl::Middleware::Static
  • MVC::Keayl::MiddlewareStack
  • MVC::Keayl::Mime
  • MVC::Keayl::Notifications
  • MVC::Keayl::PWAController
  • MVC::Keayl::ParameterFilter
  • MVC::Keayl::Parameters
  • MVC::Keayl::Params
  • MVC::Keayl::Request
  • MVC::Keayl::Response
  • MVC::Keayl::Router
  • MVC::Keayl::Routing
  • MVC::Keayl::Routing::Mount
  • MVC::Keayl::Routing::PathPattern
  • MVC::Keayl::Routing::Redirect
  • MVC::Keayl::Routing::Resources
  • MVC::Keayl::Routing::Route
  • MVC::Keayl::Routing::RouteMatch
  • MVC::Keayl::Routing::UrlHelpers
  • MVC::Keayl::SafeString
  • MVC::Keayl::Secrets
  • MVC::Keayl::Session
  • MVC::Keayl::Storage
  • MVC::Keayl::Storage::Attached
  • MVC::Keayl::Storage::Repository
  • MVC::Keayl::Storage::Service
  • MVC::Keayl::Storage::Serving
  • MVC::Keayl::Storage::Variant
  • MVC::Keayl::TestSupport
  • MVC::Keayl::View
  • MVC::Keayl::View::Context
  • MVC::Keayl::View::Handler
  • MVC::Keayl::View::Handler::HAML

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.