You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by ch...@apache.org on 2008/07/19 13:49:54 UTC

svn commit: r678138 - in /incubator/shindig/trunk/php/src: gadgets/ social-api/converters/ social-api/http/

Author: chabotc
Date: Sat Jul 19 04:49:54 2008
New Revision: 678138

URL: http://svn.apache.org/viewvc?rev=678138&view=rev
Log:
This patch adds logic to decode incomming data structures
according to the Content-Type header.

It expects a "Content-Type: application/atom+xml" for Atom input,
and a "Content-Type: application/json" header for json input.

If no Content-Type header is provided, it will assume it's json.

The decoding logic has been moved out of the RestServlet and into
the converters/Input*Converter classes and the logic is now consitent
with the output converters.

The actual atom -> internal structure hoisting still remains to be
done & will follow soon.

ps this also slipstreams in a fix to JsLibrary, since the caja feature
was being picked up by it and the res:// reference caused it to error
out, to fix this for the time being it now ignores any res:// references
and represents it as 'empty content'


Added:
    incubator/shindig/trunk/php/src/social-api/converters/InputAtomConverter.php
    incubator/shindig/trunk/php/src/social-api/converters/InputConverter.php
    incubator/shindig/trunk/php/src/social-api/converters/InputJsonConverter.php
Modified:
    incubator/shindig/trunk/php/src/gadgets/JsLibrary.php
    incubator/shindig/trunk/php/src/social-api/converters/OutputConverter.php
    incubator/shindig/trunk/php/src/social-api/http/RestServlet.php

Modified: incubator/shindig/trunk/php/src/gadgets/JsLibrary.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/JsLibrary.php?rev=678138&r1=678137&r2=678138&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/JsLibrary.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/JsLibrary.php Sat Jul 19 04:49:54 2008
@@ -88,7 +88,8 @@
 
 	static private function loadFile($fileName)
 	{
-		if (empty($fileName)) {
+		// this hack prevents loadFile from trying to load .jar resources
+		if (empty($fileName) || (strpos($fileName, 'res://') !== false)) {
 			return '';
 		}
 		if (! file_exists($fileName)) {

Added: incubator/shindig/trunk/php/src/social-api/converters/InputAtomConverter.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/converters/InputAtomConverter.php?rev=678138&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/converters/InputAtomConverter.php (added)
+++ incubator/shindig/trunk/php/src/social-api/converters/InputAtomConverter.php Sat Jul 19 04:49:54 2008
@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+/**
+ * Convert Atom representations to the internal data structure representation
+ */
+class InputAtomConverter {
+
+	public function convertPeople($requestParam)
+	{
+		$xml = simplexml_load_string($requestParam);
+		print_r($xml);
+		die();
+	}
+
+	public function convertActivities($requestParam)
+	{
+		$xml = simplexml_load_string($requestParam);
+		print_r($xml);
+		die();
+	}
+
+	public function convertAppData($requestParam)
+	{
+		$xml = simplexml_load_string($requestParam);
+		print_r($xml);
+		die();
+	}
+}

Added: incubator/shindig/trunk/php/src/social-api/converters/InputConverter.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/converters/InputConverter.php?rev=678138&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/converters/InputConverter.php (added)
+++ incubator/shindig/trunk/php/src/social-api/converters/InputConverter.php Sat Jul 19 04:49:54 2008
@@ -0,0 +1,31 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+/**
+ * Abstract class for the conversion of the RESTful API input
+ * Since the data layout between json and atom is completely
+ * different (since the structure in atom has a atom meaning
+ * and a social data meaning), we have the need to put the
+ * hoisting rules somewhere..
+ */
+abstract class InputConverter {
+	abstract public function convertPeople();
+	abstract public function convertActivities();
+	abstract public function convertAppData();	
+}
\ No newline at end of file

Added: incubator/shindig/trunk/php/src/social-api/converters/InputJsonConverter.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/converters/InputJsonConverter.php?rev=678138&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/converters/InputJsonConverter.php (added)
+++ incubator/shindig/trunk/php/src/social-api/converters/InputJsonConverter.php Sat Jul 19 04:49:54 2008
@@ -0,0 +1,44 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+/**
+ * Convert json representations to the internal data structure representation
+ */
+class InputJsonConverter {
+
+	public function convertPeople($requestParam)
+	{
+		return json_decode($requestParam, true);
+	}
+
+	public function convertActivities($requestParam)
+	{
+		return json_decode($requestParam, true);
+	}
+
+	public function convertAppData($requestParam)
+	{
+		return json_decode($requestParam, true);
+	}
+
+	public function convertJsonBatch($requestParam)
+	{
+		return json_decode($requestParam, true);
+	}
+}

Modified: incubator/shindig/trunk/php/src/social-api/converters/OutputConverter.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/converters/OutputConverter.php?rev=678138&r1=678137&r2=678138&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/converters/OutputConverter.php (original)
+++ incubator/shindig/trunk/php/src/social-api/converters/OutputConverter.php Sat Jul 19 04:49:54 2008
@@ -40,9 +40,9 @@
 	
 	public function outputPart($part, $code)
 	{
-		$boundryHeader = "{$this->boundry}\n".
-				"Content-Type: application/http;version=1.1\n".
-				"Content-Transfer-Encoding: binary\n\n";
+		$boundryHeader = "{$this->boundry}\r\n".
+				"Content-Type: application/http;version=1.1\r\n".
+				"Content-Transfer-Encoding: binary\r\n\r\n";
 		echo $boundryHeader;
 		switch ($code) {
 			case BAD_REQUEST:
@@ -65,7 +65,7 @@
 				$code = '200 OK';
 				break;
 		}
-		echo "$code\n\n";
+		echo "$code\r\n\r\n";
 		echo $part."\n";
 	}
 }

Modified: incubator/shindig/trunk/php/src/social-api/http/RestServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/social-api/http/RestServlet.php?rev=678138&r1=678137&r2=678138&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/social-api/http/RestServlet.php (original)
+++ incubator/shindig/trunk/php/src/social-api/http/RestServlet.php Sat Jul 19 04:49:54 2008
@@ -50,6 +50,9 @@
 require 'src/social-api/converters/OutputConverter.php';
 require 'src/social-api/converters/OutputAtomConverter.php';
 require 'src/social-api/converters/OutputJsonConverter.php';
+require 'src/social-api/converters/InputConverter.php';
+require 'src/social-api/converters/InputAtomConverter.php';
+require 'src/social-api/converters/InputJsonConverter.php';
 
 class RestException extends Exception {}
 
@@ -140,7 +143,9 @@
 		$params = $this->getListParams();
 		$requestItem = new RestRequestItem();
 		$url = $this->getUrl();
-		$requestParam = $this->getRequestParams();
+		$requestType = $this->getRouteFromParameter($url);
+		$requestFormat = $this->getRequestFormat();
+		$requestParam = $this->getRequestParams($requestType, $requestFormat);
 		$requestItem->createRequestItem($url, $token, $method, $params, $requestParam);
 		$responseItem = $this->getResponseItem($requestItem);
 		return array('request' => $requestItem, 'response' => $responseItem);
@@ -151,7 +156,7 @@
 		// we support both a raw http post (without application/x-www-form-urlencoded headers) like java does
 		// and a more php / curl safe version of a form post with 'request' as the post field that holds the request json data
 		if (isset($GLOBALS['HTTP_RAW_POST_DATA']) || isset($_POST['request'])) {
-			$requests = $this->getRequestParams();
+			$requests = $this->getRequestParams('jsonbatch');
 			$responses = array();
 			foreach ($requests as $key => $value) {
 				$requestItem = new RestRequestItem();
@@ -203,7 +208,7 @@
 		 * but we only want to have the last bit (the actual request), this filters that down first
 		 */
 		$emptyFound = false;
-		$requestLines = explode("\n", $request);
+		$requestLines = explode("\r\n", $request);
 		$request = '';
 		foreach ($requestLines as $line) {
 			if ($emptyFound) {
@@ -212,6 +217,9 @@
 				$emptyFound = true;
 			}
 		}
+		if (!$emptyFound) {
+			throw new Exception("Mallformed multipart structure");
+		}
 		// Now that we have the basic request in $request, split that up again & parse it into a meaningful representation
 		$firstFound = $emptyFound = false;
 		$requestLines = explode("\n", $request);
@@ -242,6 +250,9 @@
 				$request['postData'] .= $line."\n";
 			}
 		}
+		if (empty($request['method']) || empty($request['url'])) {
+			throw new Exception("Mallformed multipart structure");
+		}
 		if (empty($request['postData'])) {
 			// don't trip the requestItem into thinking there is postData when there's not
 			unset($request['postData']);
@@ -249,7 +260,8 @@
 			// if there was a post data blob present, decode it into an array, the format is based on the 
 			// content type header, which is either application/json or 
 			$format = isset($request['headers']['CONTENT_TYPE']) && strtolower($request['headers']['CONTENT_TYPE']) == 'application/atom+xml' ? 'atom' : 'json';
-			$request['postData'] = $this->decodeRequests($request['postData'], $format);
+			$requestType = $this->getRouteFromParameter($request['url']);
+			$request['postData'] = $this->decodeRequests($request['postData'], $requestType, $format);
 		}
 		return $request;
 	}
@@ -268,7 +280,7 @@
 			case 'appdata':
 				$class = 'AppDataHandler';
 				break;
-			//TODO add 'groups' here
+			//TODO add 'groups' and 'messages' here
 			default:
 				$response = new ResponseItem(NOT_IMPLEMENTED, "{$path} is not implemented");
 				break;
@@ -284,28 +296,52 @@
 		return $response;
 	}
 	
-	private function decodeRequests($requestParam, $format = 'json')
+	private function decodeRequests($requestParam, $requestType, $format = 'json')
 	{
-		// temp hack until i know what the intended way to detect format is
-		if ($format == 'json') {
-			return json_decode($requestParam, true);
-		} elseif ($format == 'atom') {
-			$xml = simplexml_load_string($requestParam);
-			print_r($xml);
-			return $xml;
-		} else {
-			throw Exception("Invalid or unsupported input format");
+		switch ($format) {
+			case 'json':
+				$inputConverter = new InputJsonConverter();
+				break;
+			case 'atom':
+				$inputConverter = new InputAtomConverter();
+				break;
+			default:
+				throw new Exception("Invalid or unsupported input format");
+				break;
 		}
+		switch ($requestType) {
+			case 'people':
+				$ret = $inputConverter->convertPeople($requestParam);
+				break;
+			case 'activities':
+				$ret = $inputConverter->convertActivities($requestParam);
+				break;
+			case 'appdata':
+				$ret = $inputConverter->convertAppData($requestParam);
+				break;
+			case 'jsonbatch':
+				// this type is only used by the internal json batch format
+				if ($format != 'json') {
+					throw new Exception("the json batch only supports the json input format");
+				}
+				$ret = $inputConverter->convertJsonBatch($requestParam);
+				break;
+			//TODO add 'groups' and 'messages' here
+			default:
+				throw new Exception("Unsupported REST call");
+				break;
+		}
+		return $ret;
 	}
 
-	private function getRequestParams()
+	private function getRequestParams($requestType, $requestFormat = 'json')
 	{
 		$post = in_array('request', $_POST) != null ? $_POST['request'] : null;
 		$requestParam = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : $post;
 		if (get_magic_quotes_gpc()) {
 			$requestParam = stripslashes($requestParam);
 		}
-		return $this->decodeRequests($requestParam);
+		return $this->decodeRequests($requestParam, $requestType, $requestFormat);
 	}
 
 	private function getRouteFromParameter($pathInfo)
@@ -379,6 +415,22 @@
 		$restParams = explode('/', $uri);
 		return $restParams;
 	}
+	
+	private function getRequestFormat()
+	{
+		if (isset($_SERVER['CONTENT_TYPE'])) {
+			switch ($_SERVER['CONTENT_TYPE']) {
+				case 'application/atom+xml':
+					return 'atom';
+				case 'application/json':
+					return 'json';
+				default:
+					throw new Exception("Invalid request content type");
+			}
+		}
+		// if no Content-Type header is set, we assume json
+		return 'json';
+	}
 
 	private function getUrl()
 	{
@@ -387,11 +439,11 @@
 
 	public function isJsonBatchUrl()
 	{
-		return strrpos($_SERVER["REQUEST_URI"], RestServlet::$JSON_BATCH_ROUTE) > 0;
+		return strrpos($_SERVER["REQUEST_URI"], RestServlet::$JSON_BATCH_ROUTE) !== false;
 	}
 
 	public function isBatchProxyUrl()
 	{
-		return strrpos($_SERVER["REQUEST_URI"], RestServlet::$BATCH_PROXY_ROUTE) > 0;
+		return strrpos($_SERVER["REQUEST_URI"], RestServlet::$BATCH_PROXY_ROUTE) !== false;
 	}
 }