NAME
YATT::Lite::WebMVC0::Connection - output buffer with request properties
SYNOPSIS
# Inside actions (*.ydo, <!yatt:action>, .htyattrc.pl), you will get
# a connection object as $CON (or $con). In templates, entity calls
# like &yatt:site_path(); implicitly use it.
# Read request parameters.
my $q = $CON->param('q');
# Build app-internal urls (mount-prefix aware).
my $path = $CON->site_path("/auth/login", [nx => $CON->current_path]);
my $url = $CON->site_url("/confirm", [token => $token]); # for emails
# Redirect (never returns).
$CON->raise_redirect($CON->site_path("/"));
# Connection is just a blessed glob handle. You can print to it.
print {$CON} "foo", "bar";
# Per-request stash.
$CON->stash->{foo} = 3;
# Raise an error page.
$CON->error("Found error in %s!", $path);
#========================================
# Under the hood, a connection is created like this
# (usually via $siteapp->make_connection($parent_fh, @config)):
# If $env is like followings:
# $env->{PATH_INFO} = '/mysite/user/hkoba'
# $env->{PATH_TRANSLATED} = '/var/www/webapps/mysite/html/user.yatt/hkoba'
my $con = YATT::Lite::WebMVC0::Connection->create(
$parent_fh,
env => $env,
site_prefix => "/mysite",
dir => "/var/www/webapps/mysite/html",
location => "/",
file => "user.yatt",
request_file => "user", # file name part as requested
subpath => "/hkoba",
# cgi => Plack::Request->new($env),
# no_nested_query => 1
);
DESCRIPTION
A connection object represents one HTTP request/response cycle. It is a blessed GLOB which buffers output printed to it, and also carries request properties (PSGI env, query parameters, the location quad: dir, location, file, subpath, and "request_file").
Most methods below are also exposed to templates as same-named entity functions (e.g. $CON->site_path(...) as &yatt:site_path(...);). See YATT::Lite::WebMVC0::SiteApp.
URL BUILDING METHODS
These four methods are the recommended way to build app-internal urls. The naming follows the widespread convention: *_path returns a path (no scheme://host), *_url returns an absolute url. All of them respect the mount point of the site ("site_prefix"), so they keep working when the app is deployed under a sub-path (e.g. behind Alias, Action or a reverse proxy).
$query is optional. It must be a HASH ref, an ARRAY ref of key-value pairs, or a query object (including $CON itself). Plain scalars and flattened key => value lists are rejected with an error (to prevent silent mistakes; see mkurl).
Note: for a link to a sibling page with a known depth, plain relative links (href="other", href="../login") are also fine and need no helper.
site_path($path, $query)
Returns site_prefix . $path . query_string. $path must start with / (it means site root, not server root). If $path is omitted, returns the site root (= "site_location").
$CON->site_path; # => /myapp/
$CON->site_path("/admin/"); # => /myapp/admin/
$CON->site_path("/list", {page => 2}); # => /myapp/list?page=2
site_url($path, $query)
Absolute url version of site_path. Use this when you need scheme://host - typically for urls put into emails. The scheme respects X-Forwarded-Proto (see mkprefix).
$CON->site_url("/confirm", [token => $token]);
# => https://example.com/myapp/confirm?token=...
current_path($query)
Returns the path of the current request (query string replaced by $query, dropped if omitted). Since $CON->mkquery accepts $CON itself as a query object, $CON->current_path($CON) reproduces the current url with its current parameters - useful to build nx (come-back url) parameters.
# Requested url: /myapp/item?page=2
$CON->current_path; # => /myapp/item
$CON->current_path([page => 3]); # => /myapp/item?page=3
$CON->current_path($CON); # => /myapp/item?page=2
current_url($query)
Absolute url version of current_path.
REDIRECT
raise_redirect($url)
redirect($url)
Sends a 302 Found redirect and never returns - it is implemented with die and unwinds the stack, like other raise_* family members ("raise_response" in YATT::Lite::Util). Do not write code after it expecting it to run. raise_redirect is an alias of redirect, preferred because the name tells this never-return behavior.
$CON->raise_redirect($CON->site_path("/login", [nx => $nx]));
Open redirect protection is built in: if $url is a plain string pointing to a foreign host (//host/... or scheme://host/...), it is rejected with 400 Bad Request. To intentionally redirect to an external site, pass a SCALAR REF:
$CON->raise_redirect(\ $external_url);
Output printed so far is discarded, and the session (if any) is flushed before the redirect.
REQUEST PARAMETER METHODS
param($name)
Returns the query/body parameter. Without arguments, returns the list of parameter names. With $CON->param($name, $value), sets the value.
Note: unless "no_nested_query" in YATT::Lite::WebMVC0::SiteApp is on, parameters like foo[0], foo[bar] are restructured into ARRAY/HASH refs (nested query) and param returns them as-is.
multi_param($name)
List context aware variant, following modern CGI convention.
param_type($name, $type, $diag, $opts)
Type-checked parameter access. $type is either a Regexp or a name of re_* patterns in YATT::Lite::RegexpNames (e.g. integer, digit, name, nonempty, any). If the value does not match, dies with 400 Bad Request (or $diag message if given). Handy for input validation:
my $id = $CON->param_type(id => 'integer');
delete_param($name)
remove_param($name)
Deletes the parameter. (Two names for the same method.)
param_exists($name)
as_hash
queryobj
as_hash returns all parameters as a plain HASH. queryobj returns the underlying parameter container (nested query HASH, Hash::MultiValue or CGI-ish object).
LOCATION INSPECTION METHODS
These methods tell where the current request is. They return values, not links - to build links, use "URL BUILDING METHODS".
Suppose the site is mounted at /myapp (SCRIPT_NAME=/myapp) and https://example.com/myapp/auth/test?q=1 is served by auth/test.yatt. Then:
site_prefix /myapp
site_location /myapp/
location /auth/
dir_location /myapp/auth/
file_location /myapp/auth/test
page_location /myapp/auth/test
request_file test
mapped_path /myapp/auth/test
request_path /myapp/auth/test
request_uri /myapp/auth/test?q=1
(If the request were /myapp/auth/test.yatt?q=1 instead, request_file would be test.yatt, and file_location / mapped_path would be /myapp/auth/test.yatt - they reproduce how the request spelled the file name. page_location stays canonical (/myapp/auth/test) regardless. Others are not affected.)
site_prefix
The mount point of the whole site (without trailing /). Comes from "site_prefix" in YATT::Lite::WebMVC0::SiteApp config, or falls back to $env->{'yatt.script_name'} (normalized SCRIPT_NAME, set by SiteApp).
site_location
site_loc
site_prefix . '/'. The url path of the site root.
location
The location of current DirApp (directory), without site_prefix. Guaranteed to end with /.
dir_location
Like "location", but with the mount prefix prepended.
file_location
The url path of the current page: "dir_location" + "request_file". Like "mapped_path", this follows how the request spelled the file name (Apache content-negotiation model: the requested name is the base name and negotiation just appends extensions to it). The file name part is empty for index requests.
page_location
Canonical url path of the current page, based on the physical file name: "dir_location" + file name without the last extension (file name part is omitted for index pages). Unlike "file_location", this is not affected by how the request spelled the url. Use this for canonical links.
request_file
The file name part as it appeared in the request: extension-less when the request omitted it, extension-ful when the request spelled it, and empty when the file name was totally omitted (index requests). In other words, file - request_file = the extension supplemented by the dispatcher.
mapped_path
Reconstruction of the url path of the current request from the mapping result: site_prefix + location + request_file + subpath. Usually this equals "request_path"; they differ when REQUEST_URI does not represent the logical location (e.g. url rewriting). In list context, returns ($prefix_location_file, $subpath).
request_path
request_uri
request_uri is $env->{REQUEST_URI} (query string included). request_path is the same with query string stripped.
is_current_file($path)
True when $path addresses the current page. $path is a site-rooted literal - the same form as the argument of site_path, so a nav link and its current-page test can share one literal:
<yatt:if "&yatt:is_current_file(/auth/login);">
<b>login</b>
<:yatt:else/>
<a href="&yatt:site_path(/auth/login);">login</a>
</yatt:if>
Accepted forms: canonical (/auth/login), physical (/auth/login.yatt), and directory form for index pages (/auth/). Mount prefix and how the request spelled the url do not affect the result. Subpath is ignored.
is_current_page($file, $page)
Compares the page name (directory-independent) and subpage (subpath) against the current request.
LOW LEVEL URL METHODS
Building blocks of the above. Usually you won't need them directly - prefer site_path and its friends for new code.
mkurl($file, $param, %opts)
The oldest url builder. Returns an absolute url by default (note: this default is opposite to site_path family).
$file selects the base path:
undefor''-
The current request path.
'.'-
The directory part of the current request path.
'name'(relative)-
Sibling file in the same directory.
/abs(starts with/)-
site_prefix . $file.
$param is passed to mkquery. %opts are:
- local => 1
-
Omit
scheme://hostpart (return path only). - mapped_path => 1
-
Use "mapped_path" (reconstruction of the requested url path from the mapping result) as the base, instead of
REQUEST_URI. Useful whenREQUEST_URIdoes not represent the logical location (e.g. url rewriting). - separator => $sep
-
Query separator. Default is
&.
Caveat: %opts comes after the positional $param. mkurl("/admin/", local => 1) is a common mistake - "local" is taken as $param. Write mkurl("/admin/", undef, local => 1), or just use site_path("/admin/").
mkpath($file, $use_mapped_path)
The path building part of mkurl.
mkquery($param, $separator)
Builds a query string from $param: a HASH ref (keys sorted), an ARRAY ref of key-value pairs (order preserved), an object with keys/get_all (like Hash::MultiValue) or param (like CGI), or a connection itself (meaning its current parameters). In scalar context, returns ?key=value&... (? included) or an empty string. In list context, returns encoded key=value pairs.
mkprefix(@extras)
Returns scheme://host[:port] + @extras. The scheme respects $env->{HTTP_X_FORWARDED_PROTO} (reverse proxy) over $env->{'psgi.url_scheme'}.
mkhost($scheme)
Returns HTTP_HOST if set, otherwise SERVER_NAME with non-default :port.
PSGI/CGI ENV METHODS
Following methods return raw request env values. Each takes an optional $default:
referer, remote_addr, request_method, script_name, path_info, query_string, server_name, server_port, server_protocol, content_length, content_type.
Caveat about script_name: $CON->script_name is the raw $env->{SCRIPT_NAME}, which may contain handler artifacts like /cgi-bin/dispatch.cgi under Apache Action mapping. On the other hand, the entity &yatt:script_name(); returns the normalized $env->{'yatt.script_name'}. For url building, use "site_prefix" (or the entity).
Also:
raw_body, uploads, upload
Delegated to Plack::Request. PSGI mode only.
file, subpath, parameters, request_file
Read-only accessors of connection properties.
SESSION METHODS
Session support is delegated to the system (SiteApp). See YATT::Lite::WebMVC0::Partial::Session2 for the actual implementation of session_* hooks.
get_session
Returns the session object if the request has (or lazily resumes) one.
start_session(@init)
Starts a new session.
delete_session
flush_session
OTHER METHODS
current_user
current_user($method, @args)
Returns the user object loaded via $system->load_current_user. With arguments, invokes $user->$method(@args) (dies if no user is loaded).
accept_language(%opts)
Parses Accept-Language header and returns preferred language(s). Options: filter => \@langs (or Regexp/HASH/CODE), long => 1 (en_US style), detail => 1 (with quality values).
my $lang = $CON->accept_language(filter => [qw/en ja/]) || 'en';
Inherited basics
From YATT::Lite::Connection (parent class): buffer (current output), flush, stash (per-request HASH for your app), set_header, list_header, cget, configure, error($fmt, @args), raise($type, $fmt, @args), error_with_status($code, $fmt, @args), logbacktrace, logdump.
SEE ALSO
YATT::Lite::WebMVC0::SiteApp (entity functions), YATT::Lite