Created
September 1, 2011 18:37
-
-
Save vti/1186895 to your computer and use it in GitHub Desktop.
metacpan jsonp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/MetaCPAN/Server.pm b/lib/MetaCPAN/Server.pm | |
index 75f687d..2f0d103 100755 | |
--- a/lib/MetaCPAN/Server.pm | |
+++ b/lib/MetaCPAN/Server.pm | |
@@ -1,9 +1,10 @@ | |
package MetaCPAN::Server; | |
+use lib 'lib'; | |
use Moose; | |
extends 'Catalyst'; | |
use CatalystX::RoleApplicator; | |
-use Plack::Middleware::ReverseProxy; | |
+use Plack::Builder; | |
use FindBin; | |
use lib "$FindBin::RealBin/../"; | |
@@ -72,8 +73,11 @@ __PACKAGE__->setup( | |
__PACKAGE__->setup_engine('PSGI'); | |
__PACKAGE__->meta->make_immutable( replace_constructor => 1 ); | |
-Plack::Middleware::ReverseProxy->wrap( | |
- sub { | |
- __PACKAGE__->run(@_); | |
- } | |
-); | |
+builder { | |
+ enable 'ReverseProxy'; | |
+ | |
+ enable_if { $_[0]->{PATH_INFO} =~ m!^/(?:author|OTHER ALLOWED PATHS GO HERE)(?:/|$)! } | |
+ 'JSONP::ElasticSearch'; | |
+ | |
+ sub { __PACKAGE__->run(@_) }; | |
+} | |
diff --git a/lib/Plack/Middleware/JSONP/ElasticSearch.pm b/lib/Plack/Middleware/JSONP/ElasticSearch.pm | |
new file mode 100644 | |
index 0000000..5e9b100 | |
--- /dev/null | |
+++ b/lib/Plack/Middleware/JSONP/ElasticSearch.pm | |
@@ -0,0 +1,43 @@ | |
+package Plack::Middleware::JSONP::ElasticSearch; | |
+use strict; | |
+use parent qw(Plack::Middleware::JSONP); | |
+use Plack::Util; | |
+use URI::Escape (); | |
+ | |
+sub call { | |
+ my ($self, $env) = @_; | |
+ | |
+ my $callback_key = $self->callback_key; | |
+ | |
+ # We cut off jsonp callback parameter because we don't want | |
+ # it to get to ElasticSearch (otherwise we get already wrapped | |
+ # JSONP response that metacpan tries to parse as JSON) | |
+ my $callback; | |
+ if ($env->{QUERY_STRING} =~ s/(?:^|&)$callback_key=([^&]+)//) { | |
+ $callback = URI::Escape::uri_unescape($1); | |
+ $callback = undef unless $callback =~ /^[\w\.\[\]]+$/; | |
+ } | |
+ | |
+ my $res = $self->app->($env); | |
+ return $res unless defined $callback; | |
+ | |
+ $self->response_cb( | |
+ $res, | |
+ sub { | |
+ my $res = shift; | |
+ if (defined $res->[2]) { | |
+ my $h = Plack::Util::headers($res->[1]); | |
+ if ($h->get('Content-Type') =~ m!/(?:json|javascript)!) { | |
+ my $body; | |
+ Plack::Util::foreach($res->[2], sub { $body .= $_[0] }); | |
+ my $jsonp = "$callback($body)"; | |
+ $res->[2] = [$jsonp]; | |
+ $h->set('Content-Length', length $jsonp); | |
+ $h->set('Content-Type', 'text/javascript'); | |
+ } | |
+ } | |
+ } | |
+ ); | |
+} | |
+ | |
+1; | |
diff --git a/t/plack/middleware/jsonp-elastic-search.t b/t/plack/middleware/jsonp-elastic-search.t | |
new file mode 100644 | |
index 0000000..c3671a1 | |
--- /dev/null | |
+++ b/t/plack/middleware/jsonp-elastic-search.t | |
@@ -0,0 +1,33 @@ | |
+use strict; | |
+use Test::More; | |
+use Plack::Test; | |
+use Plack::Builder; | |
+ | |
+my @json = ('{"foo":', '"bar"}'); | |
+my $json = join '', @json; | |
+ | |
+my $app = sub { | |
+ is($_[0]->{QUERY_STRING}, ''); | |
+ | |
+ return [200, ['Content-Type' => 'application/json'], [@json]]; | |
+}; | |
+$app = builder { | |
+ enable "Plack::Middleware::JSONP::ElasticSearch"; | |
+ $app; | |
+}; | |
+ | |
+test_psgi | |
+ app => $app, | |
+ client => sub { | |
+ my $cb = shift; | |
+ | |
+ my $res = $cb->(HTTP::Request->new(GET => 'http://localhost/')); | |
+ is $res->content_type, 'application/json'; | |
+ is $res->content, $json; | |
+ | |
+ $res = $cb->(HTTP::Request->new(GET => 'http://localhost/?callback=foo')); | |
+ is $res->content_type, 'text/javascript'; | |
+ is $res->content, "foo($json)"; | |
+ }; | |
+ | |
+done_testing; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment