Merge branch 'fix-prepare-query-parameters' of https://github.com/ap/catalyst-runtime...
John Napiorkowski [Tue, 17 Feb 2015 01:51:57 +0000 (19:51 -0600)]
Changes
Makefile.PL
lib/Catalyst.pm
lib/Catalyst/ActionRole/HTTPMethods.pm
lib/Catalyst/Controller.pm
t/aggregate/live_component_controller_httpmethods.t
t/author/spelling.t
t/lib/TestApp/Controller/HTTPMethods.pm
t/utf_incoming.t

diff --git a/Changes b/Changes
index 6939a7d..c19ab9e 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,5 +1,10 @@
 # This file documents the revision history for Perl extension Catalyst.
 
+5.90083 - 2014-01-20
+  - Fixed typo in support for OPTIONS method matching (andre++)
+  - Use new HTTP::Body and code updates to fix issue when POSTed params have
+    non UTF-8 charset encodings.
+
 5.90082 - 2015-01-10
   - Fixed a regression created in $response->from_psgi_response and test case
     to prevent it happening again.
index f862960..0b2d9b3 100644 (file)
@@ -26,7 +26,7 @@ author 'Sebastian Riedel <sri@cpan.org>';
 authority('cpan:MSTROUT');
 all_from 'lib/Catalyst/Runtime.pm';
 
-requires 'List::MoreUtils';
+equires 'List::MoreUtils';
 requires 'namespace::autoclean' => '0.09';
 requires 'namespace::clean' => '0.23';
 requires 'MooseX::Emulate::Class::Accessor::Fast' => '0.00903';
@@ -42,7 +42,7 @@ requires 'Data::Dump';
 requires 'Data::OptList';
 requires 'HTML::Entities';
 requires 'HTML::HeadParser';
-requires 'HTTP::Body'    => '1.06'; # ->cleanup(1)
+requires 'HTTP::Body'    => '1.20';
 requires 'HTTP::Headers' => '1.64';
 requires 'HTTP::Request' => '5.814';
 requires 'HTTP::Response' => '5.813';
index d6717cb..25661fe 100644 (file)
@@ -4316,6 +4316,8 @@ acme: Leon Brocard <leon@astray.com>
 
 abraxxa: Alexander Hartmaier <abraxxa@cpan.org>
 
+andrewalker: André Walker <andre@cpan.org>
+
 Andrew Bramble
 
 Andrew Ford E<lt>A.Ford@ford-mason.co.ukE<gt>
index 8b9eef8..a67d629 100644 (file)
@@ -47,13 +47,13 @@ Catalyst::ActionRole::HTTPMethods - Match on HTTP Methods
 
     sub user_base : Chained('/') CaptureArg(0) { ... }
 
-      sub get_user    : Chained('user_base') Args(1) GET { ... }
-      sub post_user   : Chained('user_base') Args(1) POST { ... }
-      sub put_user    : Chained('user_base') Args(1) PUT { ... }
-      sub delete_user : Chained('user_base') Args(1) DELETE { ... }
-      sub head_user   : Chained('user_base') Args(1) HEAD { ... }
-      sub option_user : Chained('user_base') Args(1) OPTION { ... }
-      sub option_user : Chained('user_base') Args(1) PATCH { ... }
+      sub get_user     : Chained('user_base') Args(1) GET { ... }
+      sub post_user    : Chained('user_base') Args(1) POST { ... }
+      sub put_user     : Chained('user_base') Args(1) PUT { ... }
+      sub delete_user  : Chained('user_base') Args(1) DELETE { ... }
+      sub head_user    : Chained('user_base') Args(1) HEAD { ... }
+      sub options_user : Chained('user_base') Args(1) OPTIONS { ... }
+      sub patch_user   : Chained('user_base') Args(1) PATCH { ... }
 
 
       sub post_and_put : Chained('user_base') POST PUT Args(1) { ... }
index f2ccfa8..860339c 100644 (file)
@@ -544,12 +544,12 @@ sub _parse_Does_attr {
     return Does => $self->_expand_role_shortname($value);
 }
 
-sub _parse_GET_attr    { Method => 'GET'    }
-sub _parse_POST_attr   { Method => 'POST'   }
-sub _parse_PUT_attr    { Method => 'PUT'    }
-sub _parse_DELETE_attr { Method => 'DELETE' }
-sub _parse_OPTION_attr { Method => 'OPTION' }
-sub _parse_HEAD_attr   { Method => 'HEAD'   }
+sub _parse_GET_attr     { Method => 'GET'     }
+sub _parse_POST_attr    { Method => 'POST'    }
+sub _parse_PUT_attr     { Method => 'PUT'     }
+sub _parse_DELETE_attr  { Method => 'DELETE'  }
+sub _parse_OPTIONS_attr { Method => 'OPTIONS' }
+sub _parse_HEAD_attr    { Method => 'HEAD'    }
 
 sub _expand_role_shortname {
     my ($self, @shortnames) = @_;
index 6507af1..9cc6e9f 100644 (file)
@@ -1,13 +1,17 @@
 use strict;
 use warnings;
 use Test::More;
-use HTTP::Request::Common qw/GET POST DELETE PUT /;
+use HTTP::Request::Common qw/GET POST DELETE PUT/;
  
 use FindBin;
 use lib "$FindBin::Bin/../lib";
 
 use Catalyst::Test 'TestApp';
+
+sub OPTIONS {
+    HTTP::Request->new('OPTIONS', @_);
+}
+
 is(request(GET    '/httpmethods/foo')->content, 'get');
 is(request(POST   '/httpmethods/foo')->content, 'post');
 is(request(DELETE '/httpmethods/foo')->content, 'default');
@@ -34,4 +38,12 @@ is(request(GET    '/httpmethods/check_default')->content, 'get3');
 is(request(POST   '/httpmethods/check_default')->content, 'post3');
 is(request(PUT    '/httpmethods/check_default')->content, 'chain_default');
 
+is(request(GET    '/httpmethods/opt_typo')->content, 'typo');
+is(request(POST   '/httpmethods/opt_typo')->content, 'typo');
+is(request(PUT    '/httpmethods/opt_typo')->content, 'typo');
+
+is(request(OPTIONS '/httpmethods/opt')->content, 'options');
+is(request(GET     '/httpmethods/opt')->content, 'default');
+is(request(POST    '/httpmethods/opt')->content, 'default');
+
 done_testing;
index 9ebfaf5..f55ea40 100644 (file)
@@ -24,6 +24,7 @@ add_stopwords(qw(
     chunked chunking codewise distingush equivilent plack Javascript gzipping
     ConfigLoader getline whitepaper matchable
     Andreas
+    André
     Ashton
     Axel
     Balint
index e687372..2f7476d 100644 (file)
@@ -30,6 +30,16 @@ sub any_method : Path('baz') {
     $ctx->response->body('any');
 }
 
+sub typo_option : Path('opt_typo') OPTION {
+    my ($self, $ctx) = @_;
+    $ctx->response->body('typo');
+}
+
+sub real_options : Path('opt') OPTIONS {
+    my ($self, $ctx) = @_;
+    $ctx->response->body('options');
+}
+
 sub base :Chained('/') PathPrefix CaptureArgs(0) { }
 
 sub chained_get :Chained('base') Args(0) GET {
index 76eaa87..147b222 100644 (file)
@@ -4,7 +4,7 @@ use strict;
 use Test::More;
 use HTTP::Request::Common;
 use HTTP::Message::PSGI ();
-use Encode 2.21 'decode_utf8', 'encode_utf8';
+use Encode 2.21 'decode_utf8', 'encode_utf8', 'encode';
 use File::Spec;
 use JSON::MaybeXS;
 
@@ -187,6 +187,12 @@ use JSON::MaybeXS;
     $c->res->from_psgi_response( ref($c)->to_app->($env));
   }
 
+  sub echo_arg :Local {
+    my ($self, $c) = @_;
+    $c->response->content_type('text/plain');
+    $c->response->body($c->req->body_parameters->{arg});
+  }
+
   package MyApp;
   use Catalyst;
 
@@ -427,6 +433,36 @@ SKIP: {
   is $res->content_charset, 'UTF-8';
 }
 
+{
+  my $utf8 = 'test ♥';
+  my $shiftjs = 'test テスト';
+
+  ok my $req = POST '/root/echo_arg',
+    Content_Type => 'form-data',
+      Content =>  [
+        arg0 => 'helloworld',
+        arg1 => [
+          undef, '',
+          'Content-Type' =>'text/plain; charset=UTF-8',
+          'Content' => Encode::encode('UTF-8', $utf8)],
+        arg2 => [
+          undef, '',
+          'Content-Type' =>'text/plain; charset=SHIFT_JIS',
+          'Content' => Encode::encode('SHIFT_JIS', $shiftjs)],
+        arg2 => [
+          undef, '',
+          'Content-Type' =>'text/plain; charset=SHIFT_JIS',
+          'Content' => Encode::encode('SHIFT_JIS', $shiftjs)],
+      ];
+
+  my ($res, $c) = ctx_request $req;
+
+  is $c->req->body_parameters->{'arg0'}, 'helloworld';
+  is Encode::decode('UTF-8', $c->req->body_parameters->{'arg1'}), $utf8;
+  is Encode::decode('SHIFT_JIS', $c->req->body_parameters->{'arg2'}[0]), $shiftjs;
+
+}
+
 ## should we use binmode on filehandles to force the encoding...?
 ## Not sure what else to do with multipart here, if docs are enough...