Plack::Middleware::JSONP - Wraps JSON response in JSONP if callback parameter is specified


Plack documentation Contained in the Plack distribution.

Index


Code Index:

NAME

Top

Plack::Middleware::JSONP - Wraps JSON response in JSONP if callback parameter is specified

SYNOPSIS

Top

    enable "JSONP", callback_key => 'jsonp';

DESCRIPTION

Top

Plack::Middleware::JSONP wraps JSON response, which has Content-Type value either text/javascript or application/json as a JSONP response which is specified with the callback query parameter. The name of the parameter can be set while enabling the middleware.

This middleware only works with a non-streaming response, and doesn't touch the response otherwise.

AUTHOR

Top

Tatsuhiko Miyagawa

SEE ALSO

Top

Plack


Plack documentation Contained in the Plack distribution.

package Plack::Middleware::JSONP;
use strict;
use parent qw(Plack::Middleware);
use Plack::Util;
use URI::Escape ();

use Plack::Util::Accessor qw/callback_key/;

sub prepare_app {
    my $self = shift;
    unless (defined $self->callback_key) {
        $self->callback_key('callback');
    }
}

sub call {
    my($self, $env) = @_;
    my $res = $self->app->($env);
    $self->response_cb($res, sub {
        my $res = shift;
        if (defined $res->[2]) {
            my $h = Plack::Util::headers($res->[1]);
            my $callback_key = $self->callback_key;
            if ($h->get('Content-Type') =~ m!/(?:json|javascript)! &&
                $env->{QUERY_STRING} =~ /(?:^|&)$callback_key=([^&]+)/) {
                my $cb = URI::Escape::uri_unescape($1);
                if ($cb =~ /^[\w\.\[\]]+$/) {
                    my $body;
                    Plack::Util::foreach($res->[2], sub { $body .= $_[0] });
                    my $jsonp = "$cb($body)";
                    $res->[2] = [ $jsonp ];
                    $h->set('Content-Length', length $jsonp);
                    $h->set('Content-Type', 'text/javascript');
                }
            }
        }
    });
}

1;

__END__