1package Plack::Middleware::AMF; 2 3use warnings; 4use strict; 5 6our $VERSION = '0.02'; 7 8use parent "Plack::Middleware"; 9 10use Data::AMF::Remoting; 11use Plack::Request; 12use Plack::Util; 13use Plack::Util::Accessor qw/path headers_handler message_handler/; 14use UNIVERSAL::require; 15 16sub prepare_app { 17 my $self = shift; 18 19 unless (defined $self->headers_handler) { 20 $self->headers_handler(\&_default_headers_handler); 21 } 22 23 unless (defined $self->message_handler) { 24 $self->message_handler(\&_default_message_handler); 25 } 26 27 if (ref $self->headers_handler ne 'CODE') { 28 die 'headers_handler should be a code reference'; 29 } 30 31 if (ref $self->message_handler ne 'CODE') { 32 die 'message_handler should be a code reference'; 33 } 34} 35 36sub call { 37 my $self = shift; 38 my $env = shift; 39 40 my $res = $self->_handle_amf($env); 41 42 return $res if $res; 43 44 return $self->app->($env); 45} 46 47sub _handle_amf { 48 my ($self, $env) = @_; 49 50 my $path_match = $self->path or return; 51 my $path = $env->{PATH_INFO}; 52 53 for ($path) { 54 my $matched = 'CODE' eq ref $path_match ? $path_match->($_) : $_ =~ $path_match; 55 return unless $matched; 56 } 57 58 my $req = Plack::Request->new($env); 59 my $res = $req->new_response(200); 60 61 my $remoting = Data::AMF::Remoting->new( 62 source => $req->raw_body, 63 headers_did_process => $self->headers_handler, 64 message_did_process => $self->message_handler, 65 ); 66 $remoting->run if $remoting->{source}; 67 68 $res->content_type('application/x-amf'); 69 $res->body($remoting->data); 70 71 return $res->finalize; 72} 73 74sub _default_headers_handler {} 75 76sub _default_message_handler { 77 my $message = shift; 78 79 my ($controller_name, $action_name) = split '\.', $message->target_uri; 80 81 $controller_name->require or die $@; 82 83 my $controller = $controller_name->new; 84 my $action = $controller->can($action_name); 85 86 if (defined $action) { 87 return $controller->$action(@{ $message->value }); 88 } 89} 90 911; 92__END__ 93 94=head1 NAME 95 96Plack::Middleware::AMF - The great new Plack::Middleware::AMF! 97 98=head1 VERSION 99 100Version 0.01 101 102=head1 SYNOPSIS 103 104 use Plack::Builder; 105 106 builder { 107 enable "AMF", path => qr/^\/amf\/gateway/; 108 $app 109 }; 110 111=head1 DESCRIPTION 112 113Enable this middleware to allow your Plack-based application to handle Flash Remoting and Flex RPC. 114 115=head1 CONFIGURATIONS 116 117=head2 path 118 119=head2 headers_handler 120 121=head2 message_handler 122 123=head1 METHOD 124 125=head2 prepare_app 126 127=head2 call 128 129=head1 AUTHOR 130 131Takuho Yoshizu, C<< <yoshizu at s2factory.co.jp> >> 132 133=head1 BUGS 134 135Please report any bugs or feature requests to C<bug-plack-middleware-amf at rt.cpan.org>, or through 136the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Plack-Middleware-AMF>. I will be notified, and then you'll 137automatically be notified of progress on your bug as I make changes. 138 139 140=head1 SUPPORT 141 142You can find documentation for this module with the perldoc command. 143 144 perldoc Plack::Middleware::AMF 145 146 147You can also look for information at: 148 149=over 4 150 151=item * RT: CPAN's request tracker 152 153L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Plack-Middleware-AMF> 154 155=item * AnnoCPAN: Annotated CPAN documentation 156 157L<http://annocpan.org/dist/Plack-Middleware-AMF> 158 159=item * CPAN Ratings 160 161L<http://cpanratings.perl.org/d/Plack-Middleware-AMF> 162 163=item * Search CPAN 164 165L<http://search.cpan.org/dist/Plack-Middleware-AMF/> 166 167=back 168 169 170=head1 ACKNOWLEDGEMENTS 171 172 173=head1 LICENSE AND COPYRIGHT 174 175Copyright 2010 Takuho Yoshizu. 176 177This program is free software; you can redistribute it and/or modify it 178under the terms of either: the GNU General Public License as published 179by the Free Software Foundation; or the Artistic License. 180 181See http://dev.perl.org/licenses/ for more information. 182 183 184=cut 185