our
$VERSION
= 0.01;
sub
prepare_app {
my
$self
=
shift
;
unless
(
defined
$self
->callback_key) {
$self
->callback_key(
'callback'
);
}
if
(
defined
$self
->json_key) {
my
$json_key
=
$self
->json_key() .
'|'
.
$self
->callback_key;
$self
->json_key(
$json_key
);
}
else
{
$self
->json_key(
$self
->callback_key);
}
}
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
$json_key
=
$self
->json_key;
my
$content_type
=
$h
->get(
'Content-Type'
) ||
''
;
if
((
$json_key
and
$env
->{QUERY_STRING} =~ /(?:^|&)(
$json_key
)=([^&]+)/) or
$content_type
=~ m!/(?:json|javascript)!) {
if
((
ref
$res
->[2][0] eq
'ARRAY'
) or (
ref
$res
->[2][0] eq
'HASH'
)) {
$res
->[2] = [ encode_json(
$res
->[2][0]) ];
}
if
(
defined
$self
->callback_key and $1 and $1 eq
$self
->callback_key) {
my
$cb
= URI::Escape::uri_unescape($2);
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
$res
->[2][0]);
$h
->set(
'Content-Type'
,
'application/json; charset=utf-8'
);
}
}
});
}
1;