view release on metacpan or search on metacpan
lib/Catalyst.pm view on Meta::CPAN
MyApp->config(encoding => undef);
This is recommended for temporary backwards compatibility only.
To turn it off for a single request use the L<clear_encoding>
method to turn off encoding for this request. This can be useful
when you are setting the body to be an arbitrary block of bytes,
especially if that block happens to be a block of UTF8 text.
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$/
Encoding is set on the application, but it is copied to the context object
so that you can override it on a request basis.
Be default we don't automatically encode 'application/json' since the most
common approaches to generating this type of response (Either via L<Catalyst::View::JSON>
lib/Catalyst/Controller.pm view on Meta::CPAN
wish to reuse over many actions.
See L<Catalyst::RouteMatching> for more.
B<Note>: It is highly recommended to use L<Type::Tiny> for your type constraints over
other options. L<Type::Tiny> exposed a better meta data interface which allows us to
do more and better types of introspection driving tests and debugging.
=head2 Consumes('...')
Matches the current action against the content-type of the request. Typically
this is used when the request is a POST or PUT and you want to restrict the
submitted content type. For example, you might have an HTML for that either
returns classic url encoded form data, or JSON when Javascript is enabled. In
this case you may wish to match either incoming type to one of two different
actions, for properly processing.
Examples:
sub is_json : Chained('start') Consumes('application/json') { ... }
sub is_urlencoded : Chained('start') Consumes('application/x-www-form-urlencoded') { ... }
lib/Catalyst/Delta.pod view on Meta::CPAN
$c->uri_for('/foo/bar#baz')
construction, we do not attempt to encode this and it will make a URL with a
fragment of 'baz'.
=head2 VERSION 5.90094
=head3 Multipart form POST with character set headers
When we did the UTF8 work, we punted on Form POSTs when the POST envelope was
multipart and each part had complex headers such as content-types, character
sets and so forth. In those cases instead of returning a possibly incorrect
value, we returned an object describing the part so that you could figure it
out manually. This turned out to be a bad workaround as people did not expect
to find that object. So we changed this to try much harder to get a correct
value. We still return an object if we fail but we try much harder now. If
you used to check for the object you might find that code is no longer needed
(although checking for it should not hurt or break anything either).
=head2 VERSION 5.90091
lib/Catalyst/Request.pm view on Meta::CPAN
Returns a Perl representation of body data that is not classic HTML
form data, such as JSON, XML, etc. By default, Catalyst will parse incoming
data of the type 'application/json' for POST, PUT, PATCH or DELETE methods,
and return access to that data via this method.
You may define addition data_handlers via a global configuration
setting. See L<Catalyst\DATA HANDLERS> for more information.
If the body is malformed in some way (such as undefined or not content that
matches the content-type) we raise a L<Catalyst::Exception> with the error
text as the message.
If the body content type does not match an available data handler, this
will also raise an exception.
=head2 $req->body_parameters
Returns a reference to a hash containing body (POST) parameters. Values can
be either a scalar or an arrayref containing scalars.
lib/Catalyst/UTF8.pod view on Meta::CPAN
Currently we only encode if the content type is one of the types which generally expects a
UTF8 encoding. This is determined by the following regular expression:
our $DEFAULT_ENCODE_CONTENT_TYPE_MATCH = qr{text|xml$|javascript$};
$c->response->content_type =~ /$DEFAULT_ENCODE_CONTENT_TYPE_MATCH/
This is a global variable in L<Catalyst::Response> which is stored in the C<encodable_content_type>
attribute of $c->response. You may currently alter this directly on the response or globally. In
the future we may offer a configuration setting for this.
This would match content-types like the following (examples)
text/plain
text/html
text/xml
application/javascript
application/xml
application/vnd.user+xml
You should set your content type prior to header finalization if you want L<Catalyst> to
encode.
lib/Catalyst/UTF8.pod view on Meta::CPAN
sub scalar_body :Local {
my ($self, $c) = @_;
$c->response->content_type('text/html');
$c->response->body("<p>This is scalar_body action â¥</p>");
}
In general you should need to do nothing else since L<Catalyst> will automatically encode
this string during body finalization. The only matter to watch out for is to make sure
the string has not already been encoded, as this will result in double encoding errors.
B<NOTE> pay attention to the content-type setting in the example. L<Catalyst> inspects that
content type carefully to determine if the body needs encoding).
B<NOTE> If you set the character set of the response L<Catalyst> will skip encoding IF the
character set is set to something that doesn't match $c->encoding->mime_name. We will assume
if you are setting an alternative character set, that means you want to handle the encoding
yourself. However it might be easier to set $c->encoding for a given response cycle since
you can override this for a given response. For example here's how to override the default
encoding and set the correct character set in the response:
sub override_encoding :Local {
my ($self, $c) = @_;
$c->res->content_type('text/plain');
$c->encoding(Encode::find_encoding('Shift_JIS'));
$c->response->body("ãã¹ã");
}
This will use the alternative encoding for a single response.
B<NOTE> If you manually set the content-type character set to whatever $c->encoding->mime_name
is set to, we STILL encode, rather than assume your manual setting is a flag to override. This
is done to support backward compatible assumptions (in particular L<Catalyst::View::TT> has set
a utf-8 character set in its default content-type for ages, even though it does not itself do any
encoding on the body response). If you are going to handle encoding manually you may set
$c->clear_encoding for a single request response cycle, or as in the above example set an alternative
encoding.
=head2 Encoding with streaming type responses
L<Catalyst> offers two approaches to streaming your body response. Again, you must remember
to set your content type prior to streaming, since invoking a streaming response will automatically
finalize and send your HTTP headers (and your content type MUST be one that matches the regular
expression given above.)
lib/Catalyst/UTF8.pod view on Meta::CPAN
The first streaming method is to use the C<write> method on the response object. This method
allows 'inlined' streaming and is generally used with blocking style servers.
sub stream_write :Local {
my ($self, $c) = @_;
$c->response->content_type('text/html');
$c->response->write("<p>This is stream_write action â¥</p>");
}
You may call the C<write> method as often as you need to finish streaming all your content.
L<Catalyst> will encode each line in turn as long as the content-type meets the 'encodable types'
requirement and $c->encoding is set (which it is, as long as you did not change it).
B<NOTE> If you try to change the encoding after you start the stream, this will invoke an error
response. However since you've already started streaming this will not show up as an HTTP error
status code, but rather error information in your body response and an error in your logs.
B<NOTE> If you use ->body AFTER using ->write (for example you may do this to write your HTML
HEAD information as fast as possible) we expect the contents to body to be encoded as it
normally would be if you never called ->write. In general unless you are doing weird custom
stuff with encoding this is likely to just already do the correct thing.
lib/Catalyst/UTF8.pod view on Meta::CPAN
Preference is to disable it in the View.
Other views may be similar. You should review View documentation and test during upgrading.
We tried to make sure most common views worked properly and noted all workaround but if we
missed something please alert the development team (instead of introducing a local hack into
your application that will mean nobody will ever upgrade it...).
=head2 Setting the response from an external PSGI application.
L<Catalyst::Response> allows one to set the response from an external L<PSGI> application.
If you do this, and that external application sets a character set on the content-type, we
C<clear_encoding> for the rest of the response. This is done to prevent double encoding.
B<NOTE> Even if the character set of the content type is the same as the encoding set in
$c->encoding, we still skip encoding. This is a regrettable difference from the general rule
outlined above, where if the current character set is the same as the current encoding, we
encode anyway. Nevertheless I think this is the correct behavior since the earlier rule exists
only to support backward compatibility with L<Catalyst::View::TT>.
In general if you want L<Catalyst> to handle encoding, you should avoid setting the content
type character set since Catalyst will do so automatically based on the requested response
t/http_exceptions.t view on Meta::CPAN
sub as_string { 'bad stringy bad' }
package MyApp::Controller::Root;
use base 'Catalyst::Controller';
my $psgi_app = sub {
my $env = shift;
die MyApp::Exception->new(
404, ['content-type'=>'text/plain'], ['Not Found']);
};
sub from_psgi_app :Local {
my ($self, $c) = @_;
$c->res->from_psgi_response(
$psgi_app->(
$c->req->env));
}
sub from_catalyst :Local {
my ($self, $c) = @_;
MyApp::Exception->throw(
403, ['content-type'=>'text/plain'], ['Forbidden']);
}
sub from_code_type :Local {
my $e = MyApp::AnotherException->new;
die $e;
}
sub classic_error :Local {
my ($self, $c) = @_;
Catalyst::Exception->throw("Ex Parrot");
t/http_exceptions_backcompat.t view on Meta::CPAN
sub as_string { 'bad stringy bad' }
package MyApp::Controller::Root;
use base 'Catalyst::Controller';
my $psgi_app = sub {
my $env = shift;
die MyApp::Exception->new(
404, ['content-type'=>'text/plain'], ['Not Found']);
};
sub from_psgi_app :Local {
my ($self, $c) = @_;
$c->res->from_psgi_response(
$psgi_app->(
$c->req->env));
}
sub from_catalyst :Local {
my ($self, $c) = @_;
MyApp::Exception->throw(
403, ['content-type'=>'text/plain'], ['Forbidden']);
}
sub from_code_type :Local {
my $e = MyApp::AnotherException->new;
die $e;
}
sub classic_error :Local {
my ($self, $c) = @_;
Catalyst::Exception->throw("Ex Parrot");
t/lib/TestApp/Controller/Root.pm view on Meta::CPAN
$c->res->body('Body');
}
sub test_redirect :Global {
my ($self, $c) = @_;
# Don't set content_type
# Don't set body
$c->res->redirect('/go_here');
# route for /go_here doesn't exist
# it is only for checking HTTP response code, content-type etc.
}
sub test_redirect_uri_for :Global {
my ($self, $c) = @_;
# Don't set content_type
# Don't set body
$c->res->redirect($c->uri_for('/go_here'));
# route for /go_here doesn't exist
# it is only for checking HTTP response code, content-type etc.
}
sub test_redirect_with_contenttype :Global {
my ($self, $c) = @_;
# set content_type but don't set body
$c->res->content_type('image/jpeg');
$c->res->redirect('/go_here');
# route for /go_here doesn't exist
# it is only for checking HTTP response code, content-type etc.
}
sub test_redirect_with_content :Global {
my ($self, $c) = @_;
$c->res->content_type('text/plain');
$c->res->body('Please kind sir, I beg you to go to /go_here.');
$c->res->redirect('/go_here');
# route for /go_here doesn't exist
# it is only for checking HTTP response code, content-type etc.
}
sub test_remove_body_with_304 :Global {
my ($self, $c) = @_;
$c->res->status(304);
$c->res->content_type('text/html');
$c->res->body("<html><body>Body should not be set</body></html>");
}
sub test_remove_body_with_204 :Global {
t/unicode-exception-bug.t view on Meta::CPAN
{
package TestApp;
$INC{'TestApp.pm'} = __FILE__;
use Catalyst;
use TestApp::Exception;
sub handle_unicode_encoding_exception {
my ( $self, $param_value, $error_msg ) = @_;
TestApp::Exception->throw(
200, ['content-type'=>'text/plain'], ['Bad unicode data']);
}
__PACKAGE__->setup;
}
use Catalyst::Test 'TestApp';
{
my $res = request('/ok');