1 package Catalyst::Plugin::Unicode::Encoding;
4 use base 'Class::Data::Inheritable';
11 our $CHECK = Encode::FB_CROAK | Encode::LEAVE_SRC;
13 __PACKAGE__->mk_classdata('_encoding');
20 # Let it be set to undef
21 if (my $wanted = shift) {
22 $encoding = Encode::find_encoding($wanted)
23 or Carp::croak( qq/Unknown encoding '$wanted'/ );
27 ? $c->{encoding} = $encoding
28 : $c->_encoding($encoding);
30 $encoding = ref $c && exists $c->{encoding}
41 my $body = $c->response->body;
43 return $c->next::method(@_)
44 unless defined($body);
46 my $enc = $c->encoding;
48 return $c->next::method(@_)
51 my ($ct, $ct_enc) = $c->response->content_type;
53 # Only touch 'text-like' contents
54 return $c->next::method(@_)
55 unless $c->response->content_type =~ /^text|xml$|javascript$/;
57 if ($ct_enc && $ct_enc =~ /charset=(.*?)$/) {
58 if (uc($1) ne $enc->mime_name) {
59 $c->log->debug("Unicode::Encoding is set to encode in '" .
61 "', content type is '$1', not encoding ");
62 return $c->next::method(@_);
65 $c->res->content_type($c->res->content_type . "; charset=" . $enc->mime_name);
68 # Encode expects plain scalars (IV, NV or PV) and segfaults on ref's
69 $c->response->body( $c->encoding->encode( $body, $CHECK ) )
70 if ref(\$body) eq 'SCALAR';
75 # Note we have to hook here as uploads also add to the request parameters
81 my $enc = $c->encoding;
83 for my $key (qw/ parameters query_parameters body_parameters /) {
84 for my $value ( values %{ $c->request->{$key} } ) {
86 # TODO: Hash support from the Params::Nested
87 if ( ref $value && ref $value ne 'ARRAY' ) {
90 for ( ref($value) ? @{$value} : $value ) {
91 # N.B. Check if already a character string and if so do not try to double decode.
92 # http://www.mail-archive.com/catalyst@lists.scsys.co.uk/msg02350.html
93 # this avoids exception if we have already decoded content, and is _not_ the
94 # same as not encoding on output which is bad news (as it does the wrong thing
95 # for latin1 chars for example)..
96 $_ = Encode::is_utf8( $_ ) ? $_ : $enc->decode( $_, $CHECK );
100 for my $value ( values %{ $c->request->uploads } ) {
101 $_->{filename} = $enc->decode( $_->{filename}, $CHECK )
102 for ( ref($value) eq 'ARRAY' ? @{$value} : $value );
109 my $conf = $self->config;
111 # Allow an explict undef encoding to disable default of utf-8
112 my $enc = exists $conf->{encoding} ? delete $conf->{encoding} : 'UTF-8';
113 $self->encoding( $enc );
115 return $self->next::method(@_);
124 Catalyst::Plugin::Unicode::Encoding - Unicode aware Catalyst
128 use Catalyst qw[Unicode::Encoding];
130 MyApp->config( encoding => 'UTF-8' ); # A valid Encode encoding
135 On request, decodes all params from encoding into a sequence of
136 logical characters. On response, encodes body into encoding.
144 Returns a instance of a C<Encode> encoding
146 print $c->encoding->name
150 =head1 OVERLOADED METHODS
156 Encodes body into encoding.
158 =item prepare_uploads
160 Decodes parameters, query_parameters, body_parameters and filenames
161 in file uploads into a sequence of logical characters.
165 Setups C<< $c->encoding >> with encoding specified in C<< $c->config->{encoding} >>.
171 L<Encode>, L<Encode::Encoding>, L<Catalyst::Plugin::Unicode>, L<Catalyst>.
175 Christian Hansen, C<ch@ngmedia.com>
179 Tomas Doran, C<bobtfish@bobtfish.net>
183 This library is free software . You can redistribute it and/or modify
184 it under the same terms as perl itself.