as actions that only handle JSON or actions that only understand classic
HTML forms.
- TODO: body_data should slurp classic formdata
- - TODO: remove non public Plack::Request $env keys added in previous release
+ - Removed PSGI $env keys that are added on the 'plack.request.*' namespace
+ since after discussion it was clear those keys are not part of the public
+ API. Keys removed: 'plack.request.query', 'plack.request.body',
+ 'plack.request.merged' and 'plack.request.http.body'. Altered some test
+ cases to reflect this change.
5.90049_004 - 2013-10-18
- JSON Data handler looks for both JSON::MaybeXS and JSON, and uses
sub default_data_handlers {
my ($class) = @_;
return +{
+ 'application/x-www-form-urlencoded' => sub {
+ my ($fh, $req) = @_;
+ my $params = $req->_use_hash_multivalue ? $self->body_parameters->mixed : $self->body_parameters;
+ Class::Load::load_first_existing_class('CGI::Struct::XS', 'CGI::Struct')
+ ->('build_cgi_struct')->($params)
+ },
'application/json' => sub {
Class::Load::load_first_existing_class('JSON::MaybeXS', 'JSON')
->can('decode_json')->(do { local $/; $_->getline });
# (yes, index() is faster than a regex :))
if ( index( $query_string, '=' ) < 0 ) {
$c->request->query_keywords($self->unescape_uri($query_string));
- $env->{'plack.request.query'} ||= Hash::MultiValue->new(
- map { (URI::Escape::uri_unescape($_), '') }
- split(/\+/, $query_string, -1));
-
return;
}
}
}
- $env->{'plack.request.query'} ||= Hash::MultiValue->from_mixed(\%query);
$c->request->query_parameters(
$c->request->_use_hash_multivalue ?
- $env->{'plack.request.query'}->clone :
+ Hash::MultiValue->from_mixed(\%query) :
\%query);
}
my $uploads = $request->_body->upload;
my $parameters = $request->parameters;
- my @plack_uploads;
foreach my $name (keys %$uploads) {
my $files = $uploads->{$name};
my @uploads;
filename => $upload->{filename},
);
push @uploads, $u;
-
- # Plack compatibility.
- my %copy = (%$upload, headers=>$headers);
- push @plack_uploads, $name, Plack::Request::Upload->new(%copy);
}
$request->uploads->{$name} = @uploads > 1 ? \@uploads : $uploads[0];
-
# support access to the filename as a normal param
my @filenames = map { $_->{filename} } @uploads;
# append, if there's already params with this name
$parameters->{$name} = @filenames > 1 ? \@filenames : $filenames[0];
}
}
-
- $self->env->{'plack.request.upload'} ||= Hash::MultiValue->new(@plack_uploads);
}
=head2 $self->write($c, $buffer)
has match => (is => 'rw');
has method => (is => 'rw');
has protocol => (is => 'rw');
-has query_parameters => (is => 'rw', default => sub { {} });
+has query_parameters => (is => 'rw', lazy=>1, default => sub { shift->_use_hash_multivalue ? Hash::MultiValue->new : +{} });
has secure => (is => 'rw', default => 0);
has captures => (is => 'rw', default => sub { [] });
has uri => (is => 'rw', predicate => 'has_uri');
my $body_parameters = $self->body_parameters;
my $query_parameters = $self->query_parameters;
- ## setup for downstream plack
- $self->env->{'plack.request.merged'} ||= do {
- my $query = $self->env->{'plack.request.query'} || Hash::MultiValue->new;
- my $body = $self->env->{'plack.request.body'} || Hash::MultiValue->new;
- Hash::MultiValue->new($query->flatten, $body->flatten);
- };
-
if($self->_use_hash_multivalue) {
- return $self->env->{'plack.request.merged'}->clone; # We want a copy, in case your App is evil
+ return Hash::MultiValue->new($query_parameters->flatten, $body_parameters->flatten);
}
# We copy, no references
return;
}
- # Define PSGI ENV placeholders, or for empty should there be no content
- # body (typical in HEAD or GET). Looks like from Plack::Request that
- # middleware would probably expect to see this, even if empty
-
- $self->env->{'plack.request.body'} = Hash::MultiValue->new;
- $self->env->{'plack.request.upload'} = Hash::MultiValue->new;
-
# If there is nothing to read, set body to naught and return. This
# will cause all body code to be skipped
$self->env->{'psgi.input'}->seek(0, 0); # Reset the buffer for downstream middleware or apps
}
- $self->env->{'plack.request.http.body'} = $self->_body;
- $self->env->{'plack.request.body'} = Hash::MultiValue->from_mixed($self->_body->param);
-
# paranoia against wrong Content-Length header
my $remaining = $length - $self->_read_position;
if ( $remaining > 0 ) {
my ( $self ) = @_;
$self->prepare_body if ! $self->_has_body;
- return {} unless $self->_body;
+
+ unless($self->_body) {
+ return $self->_use_hash_multivalue ? Hash::MultiValue->new : {};
+ }
return $self->_use_hash_multivalue ?
- $self->env->{'plack.request.body'}->clone :
+ Hash::MultiValue->from_mixed($self->_body->param) :
$self->_body->param;
}
extends 'Catalyst::Controller';
-sub test_psgi_keys :Local Args(1) {
- my ($self, $c, $key) = @_;
- $c->res->body($c->req->env->{$key});
+sub test_psgi_keys :Local {
+ my ($self, $c) = @_;
+ $c->res->body('ok');
}
sub from_psgi_array : Local {
ok my($res, $c) = ctx_request(POST '/test_psgi_keys?a=1&b=2', [c=>3,d=>4]);
ok $c->req->env->{"psgix.input.buffered"}, "input is buffered";
- ok $c->req->env->{"plack.request.http.body"};
- ok my $body = $c->req->env->{"plack.request.body"};
- ok my $query = $c->req->env->{"plack.request.query"};
- ok my $merged = $c->req->env->{"plack.request.merged"};
-
- is $body->get('c'), 3;
- is $body->get('d'), 4;
- is $query->get('a'), 1;
- is $query->get('b'), 2;
- is $merged->get('c'), 3;
- is $merged->get('d'), 4;
- is $merged->get('a'), 1;
- is $merged->get('b'), 2;
is $c->req->parameters->get('c'), 3;
is $c->req->parameters->get('d'), 4;