The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Changes 06
MANIFEST 02
META.json 44
META.yml 1010
Makefile.PL 55
README 11
lib/CGI/ExtDirect.pm 612
lib/CGI/ExtDirect.pod 11
t/04_headers.t 11
t/cgi-bin/api1 33
t/cgi-bin/api1.bat 01
t/cgi-bin/api2 33
t/cgi-bin/api2.bat 01
t/cgi-bin/api3 33
t/cgi-bin/api3.bat 01
t/cgi-bin/api4 33
t/cgi-bin/api4.bat 01
t/cgi-bin/env 32
t/cgi-bin/header1 32
t/cgi-bin/header2 32
t/cgi-bin/header3 32
t/cgi-bin/header4 32
t/cgi-bin/poll1 32
t/cgi-bin/poll2 32
t/cgi-bin/poll3 32
t/cgi-bin/poll4 32
t/cgi-bin/poll5 32
t/cgi-bin/router1 32
t/cgi-bin/router2 32
t/cgi-bin/router3 32
t/cgi-bin/router4 022
t/cgi-bin/router4.bat 029
t/lib/RPC/ExtDirect/Test/Util/CGI.pm 714
33 files changed (This is a version diff) 86149
@@ -1,3 +1,9 @@
+3.20  Tue Mar 31 21:46:14 PDT 2015
+    - Updated to support call metadata feature in RPC::ExtDirect 3.20
+    - Added unit tests
+    - RPC::ExtDirect depdendency bumped to 3.20
+    - CGI::Test dependency bumped to 1.100
+
 3.12  Sun Jan 18 12:10:53 PST 2015
     - Updated CDN links in examples to Ext JS 4.2.1 instead of
       outdated and no longer supported 4.0.2a.
@@ -65,6 +65,8 @@ t/cgi-bin/router2
 t/cgi-bin/router2.bat
 t/cgi-bin/router3
 t/cgi-bin/router3.bat
+t/cgi-bin/router4
+t/cgi-bin/router4.bat
 t/data/cgi-data/bar.png
 t/data/cgi-data/foo.jpg
 t/data/cgi-data/qux.txt
@@ -4,7 +4,7 @@
       "Alex Tokarev <tokarev@cpan.org>"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 6.84, CPAN::Meta::Converter version 2.132661",
+   "generated_by" : "ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.143240",
    "license" : [
       "perl_5"
    ],
@@ -22,7 +22,7 @@
    "prereqs" : {
       "build" : {
          "requires" : {
-            "CGI::Test" : "1.000",
+            "CGI::Test" : "1.100",
             "ExtUtils::MakeMaker" : "0",
             "Test::More" : "0.82"
          }
@@ -35,7 +35,7 @@
       "runtime" : {
          "requires" : {
             "CGI" : "0",
-            "RPC::ExtDirect" : "3.02",
+            "RPC::ExtDirect" : "3.20",
             "perl" : "5.006"
          }
       }
@@ -49,5 +49,5 @@
          "url" : "https://github.com/nohuhu/CGI-ExtDirect"
       }
    },
-   "version" : "3.12"
+   "version" : "3.20"
 }
@@ -3,27 +3,27 @@ abstract: 'RPC::ExtDirect gateway for CGI'
 author:
   - 'Alex Tokarev <tokarev@cpan.org>'
 build_requires:
-  CGI::Test: 1.000
-  ExtUtils::MakeMaker: 0
-  Test::More: 0.82
+  CGI::Test: '1.100'
+  ExtUtils::MakeMaker: '0'
+  Test::More: '0.82'
 configure_requires:
-  ExtUtils::MakeMaker: 0
+  ExtUtils::MakeMaker: '0'
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 6.84, CPAN::Meta::Converter version 2.132661'
+generated_by: 'ExtUtils::MakeMaker version 6.98, CPAN::Meta::Converter version 2.143240'
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
-  version: 1.4
+  version: '1.4'
 name: CGI-ExtDirect
 no_index:
   directory:
     - t
     - inc
 requires:
-  CGI: 0
-  RPC::ExtDirect: 3.02
-  perl: 5.006
+  CGI: '0'
+  RPC::ExtDirect: '3.20'
+  perl: '5.006'
 resources:
   bugtracker: https://github.com/nohuhu/CGI-ExtDirect/issues
   repository: https://github.com/nohuhu/CGI-ExtDirect
-version: 3.12
+version: '3.20'
@@ -28,22 +28,22 @@ my %CORE_REQ = (
     # 5.20 warns that CGI is going to be removed from
     # perl core in 5.22, so we require it here
     'CGI'            => 0,
-    'RPC::ExtDirect' => '3.02',
+    'RPC::ExtDirect' => '3.20',
 );
 
 my %TEST_REQ = (
     'Test::More' => '0.82', # for explain()
-    'CGI::Test'  => '1.000',
+    'CGI::Test'  => '1.100',
 );
 
 WriteMakefile(
     NAME         => 'CGI::ExtDirect',
     VERSION_FROM => 'lib/CGI/ExtDirect.pm',
-
+    
     ABSTRACT     => 'RPC::ExtDirect gateway for CGI', 
     AUTHOR       => 'Alex Tokarev <tokarev@cpan.org>',
     LICENSE      => 'perl',
-
+    
     ($MM_VERSION >= 6.64
         ? (
             TEST_REQUIRES => \%TEST_REQ,
@@ -71,7 +71,7 @@ WriteMakefile(
         ? ( META_MERGE => {
                 resources   => {
                     bugtracker  => "$github_repo/issues",
-                    repository  => "$github_repo",
+                    repository  =>  $github_repo,
                 },
             },
         )
@@ -52,7 +52,7 @@ COPYRIGHT AND LICENSE
     This module is free software; you can redistribute it and/or modify it
     under the same terms as Perl itself. See perlartistic.
 
-    Included Ext JS examples are copyright (c) 2011-2013, Sencha Inc. Example
+    Included Ext JS examples are copyright (c) 2011, Sencha Inc. Example
     code is used and distributed under GPL 3.0 license as provided by Sencha
     Inc. See http://www.sencha.com/license. Ext JS is available for download
     at http://www.sencha.com/products/extjs/
@@ -8,6 +8,7 @@ use Carp;
 use IO::Handle;
 use File::Basename qw(basename);
 
+use RPC::ExtDirect::Util ();
 use RPC::ExtDirect::Config;
 use RPC::ExtDirect::API;
 use RPC::ExtDirect;
@@ -24,7 +25,7 @@ die __PACKAGE__." requires RPC::ExtDirect 3.0+"
 # Version of this module.
 #
 
-our $VERSION = '3.12';
+our $VERSION = '3.20';
 
 ### PUBLIC CLASS METHOD (CONSTRUCTOR) ###
 #
@@ -349,14 +350,14 @@ sub _extract_post_data {
     # Here file uploads data is stored
     my @_uploads = ();
 
+    # This is to suppress a really annoying warning in CGI.pm 4.08+.
+    # I am perfectly aware of what the list context is and how to
+    # use it, thank you very much. :/
+    local $CGI::LIST_CONTEXT_WARN = 0;
+
     # Now if the form IS involved, it gets a little bit complicated
     PARAM:
     for my $param ( keys %keyword ) {
-        # This is to suppress a really annoying warning in CGI.pm 4.08+.
-        # I am perfectly aware of what the list context is and how to
-        # use it, thank you very much. :/
-        $CGI::LIST_CONTEXT_WARN = 0;
-
         # Defang CGI's idiosyncratic way of returning multi-valued params
         my @values = $cgi->param( $param );
         $keyword{ $param } = @values == 0 ? undef
@@ -378,6 +379,11 @@ sub _extract_post_data {
         };
     };
 
+    # Metadata is JSON encoded; decode_metadata lives by side effects!
+    if ( exists $keyword{metadata} ) {
+        RPC::ExtDirect::Util::decode_metadata($self, \%keyword);
+    }
+
     # Remove extType because it's meaningless later on
     delete $keyword{ extType };
 
@@ -331,7 +331,7 @@ bug reports, this is the easiest and quickest way to get your issue fixed.
 
 =head1 COPYRIGHT AND LICENSE
 
-Copyright (c) 2011-2014 Alex Tokarev E<lt>tokarev@cpan.orgE<gt>.
+Copyright (c) 2011-2015 Alex Tokarev E<lt>tokarev@cpan.orgE<gt>.
 
 This module is free software; you can redistribute it and/or modify it under
 the same terms as Perl itself. See L<perlartistic>.
@@ -109,7 +109,7 @@ __DATA__
       http_headers => {
         'Status'            => '204 No Response',
         'Content-Type'      => qr{^text/plain},
-        'Content-Length'    => '642',
+        'Content-Length'    => '1394',
         'Set-Cookie'        => 'sessionID=xyzzy; domain=.capricorn.org; '.
                                'path=/cgi-bin/database; expires=Thursday, '.
                                '25-Apr-1999 00:40:33 GMT; secure',
@@ -1,8 +1,6 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
@@ -10,7 +8,9 @@ use CGI::ExtDirect;
 use RPC::ExtDirect::Test::Pkg::Foo;
 use RPC::ExtDirect::Test::Pkg::Bar;
 use RPC::ExtDirect::Test::Pkg::Qux;
+use RPC::ExtDirect::Test::Pkg::Meta;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 my $cgi = CGI::ExtDirect->new({ debug => 1 });
@@ -18,6 +18,7 @@ use CGI::ExtDirect;
 use RPC::ExtDirect::Test::Pkg::Foo;
 use RPC::ExtDirect::Test::Pkg::Bar;
 use RPC::ExtDirect::Test::Pkg::Qux;
+use RPC::ExtDirect::Test::Pkg::Meta;
 
 my $cgi = CGI::ExtDirect->new({ debug => 1 });
 
@@ -1,8 +1,6 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
@@ -17,7 +15,9 @@ use RPC::ExtDirect::API     Namespace       => 'myApp.ns',
 use RPC::ExtDirect::Test::Pkg::Foo;
 use RPC::ExtDirect::Test::Pkg::Bar;
 use RPC::ExtDirect::Test::Pkg::Qux;
+use RPC::ExtDirect::Test::Pkg::Meta;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 my $cgi = CGI::ExtDirect->new({ debug => 1 });
@@ -25,6 +25,7 @@ use RPC::ExtDirect::API     Namespace       => 'myApp.ns',
 use RPC::ExtDirect::Test::Pkg::Foo;
 use RPC::ExtDirect::Test::Pkg::Bar;
 use RPC::ExtDirect::Test::Pkg::Qux;
+use RPC::ExtDirect::Test::Pkg::Meta;
 
 my $cgi = CGI::ExtDirect->new({ debug => 1 });
 
@@ -1,8 +1,6 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
@@ -18,7 +16,9 @@ use RPC::ExtDirect::Test::Pkg::Foo;
 use RPC::ExtDirect::Test::Pkg::Bar;
 use RPC::ExtDirect::Test::Pkg::Qux;
 use RPC::ExtDirect::Test::Pkg::PollProvider;
+use RPC::ExtDirect::Test::Pkg::Meta;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 my $cgi = CGI::ExtDirect->new({ debug => 1 });
@@ -26,6 +26,7 @@ use RPC::ExtDirect::Test::Pkg::Foo;
 use RPC::ExtDirect::Test::Pkg::Bar;
 use RPC::ExtDirect::Test::Pkg::Qux;
 use RPC::ExtDirect::Test::Pkg::PollProvider;
+use RPC::ExtDirect::Test::Pkg::Meta;
 
 my $cgi = CGI::ExtDirect->new({ debug => 1 });
 
@@ -1,8 +1,6 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI 'cookie';
@@ -19,7 +17,9 @@ use RPC::ExtDirect::Test::Pkg::Foo;
 use RPC::ExtDirect::Test::Pkg::Bar;
 use RPC::ExtDirect::Test::Pkg::Qux;
 use RPC::ExtDirect::Test::Pkg::PollProvider;
+use RPC::ExtDirect::Test::Pkg::Meta;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 my $cookie = cookie(-name=>'sessionID',
@@ -27,6 +27,7 @@ use RPC::ExtDirect::Test::Pkg::Foo;
 use RPC::ExtDirect::Test::Pkg::Bar;
 use RPC::ExtDirect::Test::Pkg::Qux;
 use RPC::ExtDirect::Test::Pkg::PollProvider;
+use RPC::ExtDirect::Test::Pkg::Meta;
 
 my $cookie = cookie(-name=>'sessionID',
                     -value=>'xyzzy',
@@ -1,14 +1,13 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
 
 use RPC::ExtDirect::Test::Pkg::Env;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 my %headers = ();
@@ -1,14 +1,13 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
 
 use RPC::ExtDirect::Test::Pkg::PollProvider;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 local $RPC::ExtDirect::Test::Pkg::PollProvider::WHAT_YOURE_HAVING = '';
@@ -1,14 +1,13 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
 
 use RPC::ExtDirect::Test::Pkg::PollProvider;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 local $RPC::ExtDirect::Test::Pkg::PollProvider::WHAT_YOURE_HAVING = '';
@@ -1,14 +1,13 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
 
 use RPC::ExtDirect::Test::Pkg::PollProvider;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 local $RPC::ExtDirect::Test::Pkg::PollProvider::WHAT_YOURE_HAVING = '';
@@ -1,8 +1,6 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI;
@@ -10,6 +8,7 @@ use CGI::ExtDirect;
 
 use RPC::ExtDirect::Test::Pkg::PollProvider;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 local $RPC::ExtDirect::Test::Pkg::PollProvider::WHAT_YOURE_HAVING = '';
@@ -1,14 +1,13 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
 
 use RPC::ExtDirect::Test::Pkg::PollProvider;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 my %headers = ();
@@ -1,14 +1,13 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
 
 use RPC::ExtDirect::Test::Pkg::PollProvider;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 my %headers = ();
@@ -1,14 +1,13 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
 
 use RPC::ExtDirect::Test::Pkg::PollProvider;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 my %headers = ();
@@ -1,14 +1,13 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
 
 use RPC::ExtDirect::Test::Pkg::PollProvider;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 my %headers = ();
@@ -1,14 +1,13 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
 
 use RPC::ExtDirect::Test::Pkg::PollProvider;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 my %headers = ();
@@ -1,8 +1,6 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
@@ -11,6 +9,7 @@ use RPC::ExtDirect::Test::Pkg::Foo;
 use RPC::ExtDirect::Test::Pkg::Bar;
 use RPC::ExtDirect::Test::Pkg::Qux;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 my %headers = ();
@@ -1,8 +1,6 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI::ExtDirect;
@@ -11,6 +9,7 @@ use RPC::ExtDirect::Test::Pkg::Foo;
 use RPC::ExtDirect::Test::Pkg::JuiceBar;
 use RPC::ExtDirect::Test::Pkg::Qux;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 # Set the cheat flag for file uploads
@@ -1,8 +1,6 @@
 #!/bin/sh
 
-exec 3<&0
-
-$PERL -x <<'END_OF_SCRIPT'
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
 #!perl
 
 use CGI 'cookie';
@@ -12,6 +10,7 @@ use RPC::ExtDirect::Test::Pkg::Foo;
 use RPC::ExtDirect::Test::Pkg::JuiceBar;
 use RPC::ExtDirect::Test::Pkg::Qux;
 
+# 2 argument open() is here for older Perls
 open STDIN, '<&3' or die "Can't reopen STDIN";
 
 # Set the cheat flag for file uploads
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+$PERL -x 3<&0 <<'END_OF_SCRIPT'
+#!perl
+
+use CGI::ExtDirect;
+
+use RPC::ExtDirect::Test::Pkg::Meta;
+
+# 2 argument open() is here for older Perls
+open STDIN, '<&3' or die "Can't reopen STDIN";
+
+my %headers = ();
+
+my $cgi = CGI::ExtDirect->new({ debug => 1 });
+
+print $cgi->route(%headers);
+
+exit 0;
+
+END_OF_SCRIPT
+
@@ -0,0 +1,29 @@
+@rem = '--*-Perl-*--
+@echo off
+if "%OS%" == "Windows_NT" goto WinNT
+perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
+goto endofperl
+:WinNT
+perl -x -S %0 %*
+if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl
+if %errorlevel% == 9009 echo You do not have Perl in your PATH.
+if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul
+goto endofperl
+@rem ';
+#!perl
+#line 15
+
+use CGI::ExtDirect;
+
+use RPC::ExtDirect::Test::Pkg::Meta;
+
+my %headers = ();
+
+my $cgi = CGI::ExtDirect->new({ debug => 1 });
+
+print $cgi->route(%headers);
+
+exit 0;
+
+__END__
+:endofperl
@@ -37,7 +37,7 @@ sub run_tests {
     my $cmp_pkg   = 'RPC::ExtDirect::Test::Util';
     my $num_tests = @run_only || @$tests;
     
-    plan tests => 4 * $num_tests;
+    plan tests => 5 * $num_tests;
 
     TEST:
     for my $test ( @$tests ) {
@@ -65,21 +65,28 @@ sub run_tests {
         my $page = $ct->$method($url, $req);
 
         if ( ok $page, "$name not empty" ) {
+            my $want_status = $output->{status};
+            my $have_status = $page->is_ok() ? 200 : $page->error_code();
+
+            is $have_status, $want_status, "$name: HTTP status";
+
             my $want_type = $output->{content_type};
             my $have_type = $page->content_type();
             
-            like $have_type, $want_type, "$name content type";
-            
-            my $want_status = $output->{status};
-            my $have_status = $page->is_ok() ? 200 : $page->error_code();
+            like $have_type, $want_type, "$name: content type";
 
-            is $have_status, $want_status, "$name HTTP status";
+            my $want_len = defined $output->{cgi_content_length}
+                         ? $output->{cgi_content_length}
+                         : $output->{content_length};
+            my $have_len = $page->content_length();
 
+            is $have_len, $want_len, "$name: content length";
+            
             my $cmp_fn = $output->{comparator};
             my $want   = $output->{cgi_content} || $output->{content};
             my $have   = $page->raw_content();
             
-            $cmp_pkg->$cmp_fn($have, $want, "$name content")
+            $cmp_pkg->$cmp_fn($have, $want, "$name: content")
                 or diag explain "Page: ", $page;
 
             $page->delete();