[Jifty-commit] jifty branch, streamy-rest, created. 37f7539899acb746cbe2680fdbbae4bd3210e6f6

Jifty commits jifty-commit at lists.jifty.org
Mon May 3 11:16:43 EDT 2010


The branch, streamy-rest has been created
        at  37f7539899acb746cbe2680fdbbae4bd3210e6f6 (commit)

- Log -----------------------------------------------------------------
commit 3463afaa79422823bc4650838326bb73a1ef5046
Author: Chia-liang Kao <clkao at clkao.org>
Date:   Thu Apr 29 19:57:45 2010 +0800

    Use streamy interface for REST action.

diff --git a/lib/Jifty/Dispatcher.pm b/lib/Jifty/Dispatcher.pm
index dcce8f5..a0d1867 100644
--- a/lib/Jifty/Dispatcher.pm
+++ b/lib/Jifty/Dispatcher.pm
@@ -762,7 +762,7 @@ Take a coderef that returns a PSGI streamy response code.
 
 sub _do_stream {
     my ( $self, $code ) = @_;
-    $self->{stream} = $code->();
+    $self->{stream} = $code->($self);
     $self->_abort;
 }
 
diff --git a/lib/Jifty/Plugin/REST/Dispatcher.pm b/lib/Jifty/Plugin/REST/Dispatcher.pm
index b82d768..6223693 100644
--- a/lib/Jifty/Plugin/REST/Dispatcher.pm
+++ b/lib/Jifty/Plugin/REST/Dispatcher.pm
@@ -39,7 +39,7 @@ on GET    '/=/search/*/**'      => \&search_items;
 
 on GET    '/=/action/*'         => \&list_action_params;
 on GET    '/=/action'           => \&list_actions;
-on POST   '/=/action/*'         => \&run_action;
+on POST   '/=/action/*'         => stream \&run_action_stream;
 
 on GET    '/='                  => \&show_help;
 on GET    '/=/help'             => \&show_help;
@@ -207,7 +207,12 @@ Returns the user's desired output format. Returns a hashref of:
 
 sub output_format {
     my $prefix = shift;
-    my $accept = (Jifty->web->request->env->{HTTP_ACCEPT} || '');
+    output_format2(Jifty->web->request->env, $prefix);
+}
+
+sub output_format2 {
+    my ($env, $prefix) = @_;
+    my $accept = ($env->{HTTP_ACCEPT} || '');
 
     my (@prefix, $url);
     if ($prefix) {
@@ -237,7 +242,7 @@ sub output_format {
             extension    => 'js',
             content_type => 'application/javascript; charset=UTF-8',
             freezer      => sub { 'var $_ = ' . Jifty::JSON::encode_json( @_ ) },
-        };
+        };use Data::Dumper;
     }
     elsif ($accept =~ qr{^(?:application/x-)?(?:perl|pl)$}i) {
         return {
@@ -331,7 +336,7 @@ sub render_as_html {
     my $prefix = shift;
     my $url = shift;
     my $content = shift;
-
+#    warn 'rendering to html: '.Dumper($content) ;use Data::Dumper;
     my $title = _("%1 - REST API", Jifty->config->framework('ApplicationName'));
 
     if (ref($content) eq 'ARRAY') {
@@ -922,7 +927,7 @@ sub show_action_form {
     last_rule;
 }
 
-=head2 run_action 
+=head2 run_action_stream
 
 Expects $1 to be the name of an action we want to run.
 
@@ -940,16 +945,18 @@ On an internal error, throws a C<500>.
 
 =cut
 
-sub run_action {
-    my ($action_name) = action($1);
-    Jifty::Util->require($action_name) or abort(404);
-    
+
+sub run_action_stream {
+    my $dispatcher = shift;
+    my $action_name = action($1);
+    Jifty::Util->require($action_name) or $dispatcher->_do_abort(404);
+
     my $args = Jifty->web->request->arguments;
     delete $args->{''};
 
-    my $action = $action_name->new( arguments => $args ) or abort(404);
+    my $action = $action_name->new( arguments => $args ) or $dispatcher->_do_abort(404);
 
-    Jifty->api->is_allowed( $action_name ) or abort(403);
+    Jifty->api->is_allowed( $action_name ) or $dispatcher->_do_abort(403);
 
     $action->validate;
 
@@ -958,27 +965,38 @@ sub run_action {
 
     if ($@) {
         warn $@;
-        abort(500);
+        $dispatcher->_do_abort(500);
     }
 
+    my $env = Jifty->web->request->env;
     my $rec = $action->{record};
-    if ($action->result->success && $rec and $rec->isa('Jifty::Record') and $rec->id) {
-        my @fragments = ('model', ref($rec), 'id', $rec->id);
-
-        my $path = join '/', '=', map { Jifty::Web->escape_uri($_) } @fragments;
-
-        my $extension = output_format(\@fragments)->{extension};
-        $path .= '.' . $extension;
-
-        my $url = Jifty->web->url(path => $path);
-
-        Jifty->web->response->status( 302 );
-        Jifty->web->response->header('Location' => $url);
-    }
-
-    outs(undef, $action->result->as_hash);
-
-    last_rule;
-}
+    return sub {
+        my $responder = shift;
+        my $writer;
+        my $code = 200;
+        my @headers;
+        if ($action->result->success && $rec and $rec->isa('Jifty::Record') and $rec->id) {
+            my @fragments = ('model', ref($rec), 'id', $rec->id);
+            my $path = join '/', '=', map { Jifty::Web->escape_uri($_) } @fragments;
+            my $extension = output_format2($env, \@fragments)->{extension};
+            $path .= '.' . $extension;
+            my $url = Jifty->web->url(path => $path);
+            push @headers, 'Location' => $url;
+            $code = 302;
+        }
 
-1;
+        my $format = output_format2($env, undef);
+        warn "==> using $format->{format}" if $main::DEBUG;
+
+        $writer = $responder->([$code,
+                                [@headers,
+                                 'Content-Type' => $format->{content_type}]]);
+        # XXX: use writer for streamy freezer.
+        my $res = $action->result->as_hash;
+        for ($format->{freezer}->($res)) {
+            Encode::_utf8_off($_);
+            $writer->write($_);
+        }
+        $writer->close;
+    };
+};
diff --git a/t/TestApp-Plugin-REST/t/02-basic-use.t b/t/TestApp-Plugin-REST/t/02-basic-use.t
index 98ab42c..efa7acc 100644
--- a/t/TestApp-Plugin-REST/t/02-basic-use.t
+++ b/t/TestApp-Plugin-REST/t/02-basic-use.t
@@ -9,7 +9,7 @@ This is a template for your own tests. Copy it and modify it.
 
 =cut
 
-use Jifty::Test::Dist tests => 87, actual_server => 1;
+use Jifty::Test::Dist tests => 88, actual_server => 1;
 use Jifty::Test::WWW::Mechanize;
 
 my $server  = Jifty::Test->make_server;
@@ -159,6 +159,8 @@ $mech->get_ok('/=/action/DoSomething');
 is($mech->status, 200);
 $mech->get_ok('/=/action/TestApp::Plugin::REST::Action::DoSomething');
 is($mech->status, 200);
+$mech->get('/=/action/TestApp.Plugin.REST.Action.DoSomethingBad');
+is($mech->status, 404);
 $mech->get_ok('/=/action/TestApp.Plugin.REST.Action.DoSomething');
 is($mech->status, 200);
 
diff --git a/t/TestApp-Plugin-REST/t/03-format.t b/t/TestApp-Plugin-REST/t/03-format.t
index 65f2236..97f56e7 100644
--- a/t/TestApp-Plugin-REST/t/03-format.t
+++ b/t/TestApp-Plugin-REST/t/03-format.t
@@ -2,7 +2,7 @@
 use warnings;
 use strict;
 
-use Jifty::Test::Dist tests => 103;
+use Jifty::Test::Dist tests => 103, actual_server => 1;
 use Jifty::Test::WWW::Mechanize;
 
 my $server  = Jifty::Test->make_server;

commit 5cb1186b7a2e15c321afc8f7d1b8ed8af5f3dea3
Author: Chia-liang Kao <clkao at clkao.org>
Date:   Thu Apr 29 21:26:26 2010 +0800

    Use streamy interface for REST xml output.

diff --git a/lib/Jifty/Plugin/REST/Dispatcher.pm b/lib/Jifty/Plugin/REST/Dispatcher.pm
index 6223693..63e0dca 100644
--- a/lib/Jifty/Plugin/REST/Dispatcher.pm
+++ b/lib/Jifty/Plugin/REST/Dispatcher.pm
@@ -257,7 +257,7 @@ sub output_format2 {
             format       => 'XML',
             extension    => 'xml',
             content_type => 'text/xml; charset=UTF-8',
-            freezer      => \&render_as_xml,
+            freezer_stream => \&render_as_xml_stream,
         };
     }
     # if we ever have a non-html fallback case, we should be checking for an
@@ -302,26 +302,30 @@ sub outs {
     last_rule;
 }
 
-our $xml_config = { SuppressEmpty   => '',
-                    NoAttr          => 1,
-                    RootName        => 'data' };
-
 =head2 render_as_xml DATASTRUCTURE
 
 Attempts to render DATASTRUCTURE as simple, tag-based XML.
 
 =cut
 
-sub render_as_xml {
-    my $content = shift;
+sub render_as_xml_stream {
+    my ($writer, $content) = @_;
+
+    my $xmlout = sub {
+        XMLout($_[0],
+               SuppressEmpty   => '',
+               NoAttr          => 1,
+               RootName        => 'data',
+               OutputFile      => $writer);
+    };
 
     if (ref($content) eq 'ARRAY') {
-        return XMLout({value => $content}, %$xml_config);
+        return $xmlout->({ value => $content });
     }
     elsif (ref($content) eq 'HASH') {
-        return XMLout($content, %$xml_config);
+        return $xmlout->($content);
     } else {
-        return XMLout({value => $content}, %$xml_config)
+        return $xmlout->({ value => $content });
     }
 }
 
@@ -991,8 +995,16 @@ sub run_action_stream {
         $writer = $responder->([$code,
                                 [@headers,
                                  'Content-Type' => $format->{content_type}]]);
-        # XXX: use writer for streamy freezer.
         my $res = $action->result->as_hash;
+
+        if ( $format->{freezer_stream} ) {
+            my $w = Plack::Util::inline_object(%$writer,
+                                           print => sub { $writer->write(@_)});
+            $format->{freezer_stream}->($w, $res);
+            $writer->close;
+            return;
+        }
+
         for ($format->{freezer}->($res)) {
             Encode::_utf8_off($_);
             $writer->write($_);

commit 91ea879edfd1243a6206ae3fe6794c0ca89c5ba2
Author: Chia-liang Kao <clkao at clkao.org>
Date:   Sun May 2 20:08:24 2010 +0800

    get headers from current response, so the REST streamy response has cookies

diff --git a/lib/Jifty/Plugin/REST/Dispatcher.pm b/lib/Jifty/Plugin/REST/Dispatcher.pm
index 63e0dca..6b32289 100644
--- a/lib/Jifty/Plugin/REST/Dispatcher.pm
+++ b/lib/Jifty/Plugin/REST/Dispatcher.pm
@@ -974,11 +974,12 @@ sub run_action_stream {
 
     my $env = Jifty->web->request->env;
     my $rec = $action->{record};
+    my $res = Jifty->web->response->finalize;
     return sub {
         my $responder = shift;
         my $writer;
         my $code = 200;
-        my @headers;
+        my @headers = @{$res->[1]};
         if ($action->result->success && $rec and $rec->isa('Jifty::Record') and $rec->id) {
             my @fragments = ('model', ref($rec), 'id', $rec->id);
             my $path = join '/', '=', map { Jifty::Web->escape_uri($_) } @fragments;

commit 7fb5a04844958ec2c6b8918ac2094d7ca014ff98
Author: Chia-liang Kao <clkao at clkao.org>
Date:   Mon May 3 00:56:24 2010 +0800

    restore xml freezer as it's still used by outs()

diff --git a/lib/Jifty/Plugin/REST/Dispatcher.pm b/lib/Jifty/Plugin/REST/Dispatcher.pm
index 6b32289..e55a023 100644
--- a/lib/Jifty/Plugin/REST/Dispatcher.pm
+++ b/lib/Jifty/Plugin/REST/Dispatcher.pm
@@ -257,6 +257,7 @@ sub output_format2 {
             format       => 'XML',
             extension    => 'xml',
             content_type => 'text/xml; charset=UTF-8',
+            freezer      => \&render_as_xml,
             freezer_stream => \&render_as_xml_stream,
         };
     }
@@ -308,6 +309,11 @@ Attempts to render DATASTRUCTURE as simple, tag-based XML.
 
 =cut
 
+sub render_as_xml {
+    my $content = shift;
+    return render_as_xml_stream(undef, $content);
+}
+
 sub render_as_xml_stream {
     my ($writer, $content) = @_;
 

commit 37f7539899acb746cbe2680fdbbae4bd3210e6f6
Author: Chia-liang Kao <clkao at clkao.org>
Date:   Mon May 3 00:59:26 2010 +0800

    encode for streamy output.

diff --git a/lib/Jifty/Plugin/REST/Dispatcher.pm b/lib/Jifty/Plugin/REST/Dispatcher.pm
index e55a023..42294ce 100644
--- a/lib/Jifty/Plugin/REST/Dispatcher.pm
+++ b/lib/Jifty/Plugin/REST/Dispatcher.pm
@@ -1005,16 +1005,20 @@ sub run_action_stream {
         my $res = $action->result->as_hash;
 
         if ( $format->{freezer_stream} ) {
-            my $w = Plack::Util::inline_object(%$writer,
-                                           print => sub { $writer->write(@_)});
+            my $w = Plack::Util::inline_object
+                (%$writer,
+                 print => sub {
+                     $writer->write(map { Encode::is_utf8($_)
+                             ? Encode::encode('utf8', $_) : $_ } @_ );
+                 });
             $format->{freezer_stream}->($w, $res);
             $writer->close;
             return;
         }
 
         for ($format->{freezer}->($res)) {
-            Encode::_utf8_off($_);
-            $writer->write($_);
+            $writer->write(Encode::is_utf8($_)
+                    ? Encode::encode('utf8', $_) : $_);
         }
         $writer->close;
     };

-----------------------------------------------------------------------


More information about the Jifty-commit mailing list