lazy => 1,
);
sub _build_response_constructor_args {
- my $self = shift;
- { _log => $self->log };
+ return +{
+ _log => $_[0]->log,
+ encoding => $_[0]->encoding,
+ };
}
has namespace => (is => 'rw');
our $RECURSION = 1000;
our $DETACH = Catalyst::Exception::Detach->new;
our $GO = Catalyst::Exception::Go->new;
+our $DEFAULT_ENCODE_CONTENT_TYPE_MATCH = qr{text|xml$|javascript$};
#I imagine that very few of these really need to be class variables. if any.
#maybe we should just make them attributes with a default?
__PACKAGE__->_encode_check(Encode::FB_CROAK | Encode::LEAVE_SRC);
# Remember to update this in Catalyst::Runtime as well!
-our $VERSION = '5.90080_001';
+our $VERSION = '5.90079_003';
$VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases
sub import {
=head2 $c->uri_for( $action, \@captures?, @args?, \%query_values? )
+=head2 $c->uri_for( $action, [@captures, @args], \%query_values? )
+
Constructs an absolute L<URI> object based on the application root, the
provided path, and the additional arguments and query parameters provided.
When used as a string, provides a textual URI. If you need more flexibility
# Path to a static resource
$c->uri_for('/static/images/logo.png');
+In general the scheme of the generated URI object will follow the incoming request
+however if your targeted action or action chain has the Scheme attribute it will
+use that instead.
+
=cut
sub uri_for {
}
}
+ my $target_action = $path->$_isa('Catalyst::Action') ? $path : undef;
if ( $path->$_isa('Catalyst::Action') ) { # action object
s|/|%2F|g for @encoded_args;
my $captures = [ map { s|/|%2F|g; $_; }
# ->uri_for( $action, \@captures_and_args, \%query_values? )
if( !@encoded_args && $action->number_of_args ) {
my $expanded_action = $c->dispatcher->expand_action( $action );
-
my $num_captures = $expanded_action->number_of_captures;
unshift @encoded_args, splice @$captures, $num_captures;
}
my ($base, $class) = ('/', 'URI::_generic');
if(blessed($c)) {
$base = $c->req->base;
- $class = ref($base);
+ if($target_action) {
+ $target_action = $c->dispatcher->expand_action($target_action);
+ if(my $s = $target_action->scheme) {
+ $s = lc($s);
+ $class = "URI::$s";
+ $base->scheme($s);
+ } else {
+ $class = ref($base);
+ }
+ } else {
+ $class = ref($base);
+ }
+
$base =~ s{(?<!/)$}{/};
}
my ($ct, $ct_enc) = $c->response->content_type;
# Only touch 'text-like' contents
- if($c->response->content_type =~ /^text|xml$|javascript$/) {
+ if($c->response->content_type =~ /$DEFAULT_ENCODE_CONTENT_TYPE_MATCH/) {
if ($ct_enc && $ct_enc =~ /charset=([^;]*)/) {
if (uc($1) ne uc($enc->mime_name)) {
$c->log->debug("Catalyst encoding config is set to encode in '" .
return unless $enc;
# Only touch 'text-like' contents
- if($c->response->content_type =~ /^text|xml$|javascript$/) {
+ if($c->response->content_type =~ /$DEFAULT_ENCODE_CONTENT_TYPE_MATCH/) {
if (ref(\$body) eq 'SCALAR') {
$c->response->body( $c->encoding->encode( $body, $c->_encode_check ) );
}
By default encoding is now 'UTF-8'. You may turn it off by setting
the encoding configuration to undef.
+Encoding is automatically applied when the content-type is set to
+a type that can be encoded. Currently we encode when the content type
+matches the following regular expression:
+
+ $content_type =~ /^text|xml$|javascript$/
+
+The value of this regex is contained in the global variable
+
+ $Catalyst::DEFAULT_ENCODE_CONTENT_TYPE_MATCH
+
+This may change in the future. Be default we don't automatically
+encode 'application/json' since the most popular JSON encoders (such
+as L<JSON::MaybeXS> which is the library that L<Catalyst> can make use
+of) will do the UTF8 encoding and decoding automatically. Having it on
+in Catalyst could result in double encoding.
+
+If you are producing JSON response in an unconventional manner (such
+as via a template or manual strings) you should perform the UTF8 encoding
+manually as well such as to conform to the JSON specification.
+
=head2 Methods
=over 4