my %p = ( _log => $self->log );
$p{_uploadtmp} = $self->_uploadtmp if $self->_has_uploadtmp;
$p{data_handlers} = {$self->registered_data_handlers};
+ $p{_use_hash_multivalue} = $self->config->{use_hash_multivalue_in_request}
+ if $self->config->{use_hash_multivalue_in_request};
\%p;
}
# Remember to update this in Catalyst::Runtime as well!
-our $VERSION = '5.90049_003';
+our $VERSION = '5.90049_004';
sub import {
my ( $class, @arguments ) = @_;
=head2 default_data_handlers
-Default Data Handlers that come bundled with L<Catalyst>. Currently there is
-only one default data handler, for 'application/json'. This is used to parse
-incoming JSON into a Perl data structure. It used either L<JSON::MaybeXS> or
-L<JSON>, depending on which is installed. This allows you to fail back to
-L<JSON:PP>, which is a Pure Perl JSON decoder, and has the smallest dependency
-impact.
+Default Data Handlers that come bundled with L<Catalyst>. Currently there are
+only two default data handlers, for 'application/json' and an alternative to
+'application/x-www-form-urlencoded' which supposed nested form parameters via
+L<CGI::Struct> or via L<CGI::Struct::XS> IF you've installed it.
+
+The 'application/json' data handler is used to parse incoming JSON into a Perl
+data structure. It used either L<JSON::MaybeXS> or L<JSON>, depending on which
+is installed. This allows you to fail back to L<JSON:PP>, which is a Pure Perl
+JSON decoder, and has the smallest dependency impact.
Because we don't wish to add more dependencies to L<Catalyst>, if you wish to
use this new feature we recommend installing L<JSON> or L<JSON::MaybeXS> in
sub default_data_handlers {
my ($class) = @_;
return +{
+ 'application/x-www-form-urlencoded' => sub {
+ my ($fh, $req) = @_;
+ my $params = $req->_use_hash_multivalue ? $req->body_parameters->mixed : $req->body_parameters;
+ Class::Load::load_first_existing_class('CGI::Struct::XS', 'CGI::Struct')
+ ->can('build_cgi_struct')->($params);
+ },
'application/json' => sub {
Class::Load::load_first_existing_class('JSON::MaybeXS', 'JSON')
->can('decode_json')->(do { local $/; $_->getline });
=item *
+C<use_hash_multivalue_in_request>
+
+In L<Catalyst::Request> the methods C<query_parameters>, C<body_parametes>
+and C<parameters> return a hashref where values might be scalar or an arrayref
+depending on the incoming data. In many cases this can be undesirable as it
+leads one to writing defensive code like the following:
+
+ my ($val) = ref($c->req->parameters->{a}) ?
+ @{$c->req->parameters->{a}} :
+ $c->req->parameters->{a};
+
+Setting this configuration item to true will make L<Catalyst> populate the
+attributes underlying these methods with an instance of L<Hash::MultiValue>
+which is used by L<Plack::Request> and others to solve this very issue. You
+may prefer this behavior to the default, if so enable this option (be warned
+if you enable it in a legacy application we are not sure if it is completely
+backwardly compatible).
+
+=item *
+
C<psgi_middleware> - See L<PSGI MIDDLEWARE>.
=item *