Author: bhofmann
Date: Wed Nov 3 09:28:22 2010
New Revision: 1030372
URL: http://svn.apache.org/viewvc?rev=1030372&view=rev
Log:
SHINDIG-1459: added JSONP support for PHP Shindig REST and RPC API
Modified:
shindig/trunk/php/src/social/converters/OutputJsonConverter.php
shindig/trunk/php/src/social/servlet/JsonRpcServlet.php
shindig/trunk/php/test/social/OutputJsonConverterTest.php
Modified: shindig/trunk/php/src/social/converters/OutputJsonConverter.php
URL:
http://svn.apache.org/viewvc/shindig/trunk/php/src/social/converters/OutputJsonConverter.php?rev=1030372&r1=1030371&r2=1030372&view=diff
==============================================================================
--- shindig/trunk/php/src/social/converters/OutputJsonConverter.php (original)
+++ shindig/trunk/php/src/social/converters/OutputJsonConverter.php Wed Nov 3
09:28:22 2010
@@ -32,11 +32,7 @@ class OutputJsonConverter extends Output
}
// several service calls return a null value
if (! is_null($response)) {
- if (Config::get('debug')) {
- echo self::json_format(json_encode($response)); // TODO: add a query
option to pretty-print json output
- } else {
- echo json_encode($response);
- }
+ $this->encodeAndSendResponse($response);
}
}
@@ -51,7 +47,25 @@ class OutputJsonConverter extends Output
}
function outputJsonBatch(Array $responses, SecurityToken $token) {
- echo json_encode(array("responses" => $responses, "error" => false));
+ $this->encodeAndSendResponse(array("responses" => $responses, "error" =>
false));
+ }
+
+ /**
+ * encodes data to json, adds jsonp callback if requested and sends response
+ * to client
+ *
+ * @param array $data
+ */
+ private function encodeAndSendResponse($data) {
+ if (isset($_GET['callback']) && preg_match('/^[a-zA-Z0-9\_\.]*$/',
$_GET['callback'])) {
+ echo $_GET['callback'] . '(' . json_encode($data) . ')';
+ return;
+ }
+ if (Config::get('debug')) {
+ echo self::json_format(json_encode($data)); // TODO: add a query
option to pretty-print json output
+ } else {
+ echo json_encode($data);
+ }
}
/**
Modified: shindig/trunk/php/src/social/servlet/JsonRpcServlet.php
URL:
http://svn.apache.org/viewvc/shindig/trunk/php/src/social/servlet/JsonRpcServlet.php?rev=1030372&r1=1030371&r2=1030372&view=diff
==============================================================================
--- shindig/trunk/php/src/social/servlet/JsonRpcServlet.php (original)
+++ shindig/trunk/php/src/social/servlet/JsonRpcServlet.php Wed Nov 3 09:28:22
2010
@@ -86,7 +86,7 @@ class JsonRpcServlet extends ApiServlet
$responseItem = $this->getJSONResponse($key,
$this->getResponseItem($responses[$i]));
$result[] = $responseItem;
}
- echo json_encode($result);
+ $this->encodeAndSendResponse($result);
}
public function dispatch($request, $token) {
@@ -99,7 +99,7 @@ class JsonRpcServlet extends ApiServlet
// TODO: should use shared deadline across each request
$response = $this->getResponseItem($this->handleRequestItem($requestItem));
$result = $this->getJSONResponse($key, $response);
- echo json_encode($result);
+ $this->encodeAndSendResponse($result);
}
private function getJSONResponse($key, ResponseItem $responseItem) {
@@ -136,9 +136,25 @@ class JsonRpcServlet extends ApiServlet
return $error;
}
+ /**
+ * encodes data to json, adds jsonp callback if requested and sends response
+ * to client
+ *
+ * @param array $data
+ */
+ private function encodeAndSendResponse($data) {
+ // TODO: Refactor this class to use the OutputJsonConverter, so that we do
not have to duplicate
+ // encoding and JSONP handling here
+ if (isset($_GET['callback']) && preg_match('/^[a-zA-Z0-9\_\.]*$/',
$_GET['callback'])) {
+ echo $_GET['callback'] . '(' . json_encode($data) . ')';
+ return;
+ }
+ echo json_encode($data);
+ }
+
public function sendError(ResponseItem $responseItem) {
$error = $this->getErrorJson($responseItem);
- echo json_encode($error);
+ $this->encodeAndSendResponse($error);
}
private function sendBadRequest($t, $response) {
Modified: shindig/trunk/php/test/social/OutputJsonConverterTest.php
URL:
http://svn.apache.org/viewvc/shindig/trunk/php/test/social/OutputJsonConverterTest.php?rev=1030372&r1=1030371&r2=1030372&view=diff
==============================================================================
--- shindig/trunk/php/test/social/OutputJsonConverterTest.php (original)
+++ shindig/trunk/php/test/social/OutputJsonConverterTest.php Wed Nov 3
09:28:22 2010
@@ -74,5 +74,44 @@ class OutputJsonConverterTest extends PH
$this->assertEquals($expectedJson, $outputJson);
}
+ public function testOutputJsonPResponse() {
+ $_GET['callback'] = 'cb';
+ $outputConverter = new OutputJsonConverter();
+ $servletRequest = array('url' => '/people/1/@self');
+ $token = BasicSecurityToken::createFromValues('owner', 'viewer', 'app',
'domain', 'appUrl', '1', 'default');
+ $requestItem = RestRequestItem::createWithRequest($servletRequest, $token,
'convertJson', $outputConverter);
+ $requestItem->applyUrlTemplate("/people/{userId}/{groupId}/{personId}");
+ $response = array(
+ 'entry' => array('isOwner' => false, 'isViewer' => false,
'displayName' => '1 1',
+ 'id' => '1'));
+ $responseItem = new ResponseItem(null, null, $response);
+ ob_start();
+ $outputConverter->outputResponse($responseItem, $requestItem);
+ $output = ob_get_clean();
+ $expected =
'cb({"entry":{"isOwner":false,"isViewer":false,"displayName":"1 1","id":"1"}})';
+ unset($_GET['callback']);
+ $this->assertEquals($expected, $output);
+ }
+
+ public function testOutputJsonPResponseWithInvalidCallback() {
+ $_GET['callback'] = 'alert(1);cb';
+ $outputConverter = new OutputJsonConverter();
+ $servletRequest = array('url' => '/people/1/@self');
+ $token = BasicSecurityToken::createFromValues('owner', 'viewer', 'app',
'domain', 'appUrl', '1', 'default');
+ $requestItem = RestRequestItem::createWithRequest($servletRequest, $token,
'convertJson', $outputConverter);
+ $requestItem->applyUrlTemplate("/people/{userId}/{groupId}/{personId}");
+ $response = array(
+ 'entry' => array('isOwner' => false, 'isViewer' => false,
'displayName' => '1 1',
+ 'id' => '1'));
+ $responseItem = new ResponseItem(null, null, $response);
+ ob_start();
+ $outputConverter->outputResponse($responseItem, $requestItem);
+ $output = ob_get_clean();
+ $expected = '{"entry":{"isOwner":false,"isViewer":false,"displayName":"1
1","id":"1"}}';
+ unset($_GET['callback']);
+ $outputJson = json_decode($output);
+ $expectedJson = json_decode($expected);
+ $this->assertEquals($expectedJson, $outputJson);
+ }
}