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 2009/02/15 18:35:07 UTC
svn commit: r744702 [2/3] - in /incubator/shindig/trunk/php: ./ config/
src/common/ src/gadgets/ src/gadgets/render/ src/gadgets/rewrite/
src/gadgets/servlet/ test/misc/
Added: incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php?rev=744702&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php (added)
+++ incubator/shindig/trunk/php/src/gadgets/MakeRequestHandler.php Sun Feb 15 17:35:05 2009
@@ -0,0 +1,274 @@
+<?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.
+ */
+
+// according to features/core/io.js, this is high on the list of things to scrap
+define('UNPARSEABLE_CRUFT', "throw 1; < don't be evil' >");
+
+/**
+ * Handles the gadget.io.makeRequest requests
+ */
+class MakeRequestHandler extends ProxyBase {
+ public $signingFetcher;
+
+ public function __construct($context, $signingFetcher) {
+ $this->context = $context;
+ $this->signingFetcher = $signingFetcher;
+ }
+
+ /**
+ * Fetches content and returns it in JSON format
+ *
+ * @param string $url the url to fetch
+ * @param GadgetSigner $signer the request signer to use
+ * @param string $method the http method to use (get or post) in making the request
+ */
+ public function fetchJson($url, $signer, $method) {
+ $url = $this->validateUrl($url);
+ // Fetch the content and convert it into JSON.
+ // TODO: Fetcher needs to handle variety of HTTP methods.
+ $result = $this->fetchContentDivert($url, $method, $signer);
+ if (! isset($result)) {
+ //OAuthFetcher only
+ $metadata = $this->oauthFetcher->getResponseMetadata();
+ $json = array($url => $metadata);
+ $json = json_encode($json);
+ $output = UNPARSEABLE_CRUFT . $json;
+ $this->setCachingHeaders();
+ header("Content-Type: application/json; charset=utf-8", true);
+ echo $output;
+ die();
+ }
+ $status = (int)$result->getHttpCode();
+ header("HTTP/1.1 $status", true);
+ header("Content-Type: application/json; charset=utf-8", true);
+ $output = '';
+ if (isset($_REQUEST['contentType']) && $_REQUEST['contentType'] == 'FEED' && $status == 200) {
+ $this->parseFeed($result, $url);
+ } else {
+ $resp = $result->getResponseContent();
+ }
+ $json = array($url => array('body' => $resp, 'rc' => $status));
+ $json = json_encode($json);
+ $output = UNPARSEABLE_CRUFT . $json;
+ $this->setCachingHeaders();
+ echo $output;
+ }
+
+ /**
+ * Fetches content using either OAUTH, SIGNED or NONE type signing
+ *
+ * @param string $url
+ * @param string $method
+ * @param SingingFetcher $signer
+ * @return RemoteContentRequest
+ */
+ private function fetchContentDivert($url, $method, $signer) {
+ $authz = isset($_GET['authz']) ? $_GET['authz'] : (isset($_POST['authz']) ? $_POST['authz'] : '');
+ $token = $this->context->extractAndValidateToken($signer);
+ switch (strtoupper($authz)) {
+ case 'SIGNED':
+ $fetcher = $this->signingFetcher->getSigningFetcher(new BasicRemoteContentFetcher(), $token);
+ return $fetcher->fetch($url, $method);
+ case 'OAUTH':
+ $params = new OAuthRequestParams();
+ $fetcher = $this->signingFetcher->getSigningFetcher(new BasicRemoteContentFetcher(), $token);
+ $oAuthFetcherFactory = new OAuthFetcherFactory($fetcher);
+ $this->oauthFetcher = $oAuthFetcherFactory->getOAuthFetcher($fetcher, $token, $params);
+ $request = new RemoteContentRequest($url);
+ $request->createRemoteContentRequestWithUri($url);
+ return $this->oauthFetcher->fetch($request);
+ }
+ return $this->fetchContent($url, $method);
+ }
+
+ /**
+ * Handles (RSS & Atom) Type.FEED parsing using Zend's feed parser
+ *
+ * @return response string, either a json encoded feed structure or an error message
+ */
+ private function parseFeed($result, $url) {
+ require 'external/Zend/Feed.php';
+ $numEntries = $_REQUEST['numEntries'];
+ $getSummaries = ! empty($_REQUEST['getSummaries']) && $_REQUEST['getSummaries'] != 'false' ? true : false;
+ $channel = array();
+ if ((int)$result->getHttpCode() == 200) {
+ $content = $result->getResponseContent();
+ try {
+ $feed = Zend_Feed::importString($content);
+ if ($feed instanceof Zend_Feed_Rss) {
+ // Try get author
+ if ($feed->author()) {
+ $author = $feed->author();
+ } else {
+ if ($feed->creator()) {
+ $author = $feed->creator();
+ } else {
+ $author = null;
+ }
+ }
+ // Loop over each channel item and store relevant data
+ $counter = 0;
+ $channel['Entry'] = array();
+ foreach ($feed as $item) {
+ if ($counter >= $numEntries) {
+ break;
+ }
+ $_entry = array();
+ $_entry['Title'] = $item->title();
+ $_entry['Link'] = $item->link();
+ if ($getSummaries && $item->description()) {
+ $_entry['Summary'] = $item->description();
+ }
+ $date = 0;
+ if ($item->date()) {
+ $date = strtotime($item->date());
+ } else {
+ if ($item->pubDate()) {
+ $date = strtotime($item->pubDate());
+ }
+ }
+ $_entry['Date'] = $date;
+ $channel['Entry'][] = $_entry;
+ // Remember author if first found
+ if (empty($author) && $item->author()) {
+ $author = $item->author();
+ } else if ($item->creator()) {
+ $author = $item->creator();
+ }
+ $counter ++;
+ }
+ $channel['Title'] = $feed->title();
+ $channel['URL'] = $url;
+ $channel['Description'] = $feed->description();
+ if ($feed->link()) {
+ if (is_array($feed->link())) {
+ foreach ($feed->link() as $_link) {
+ if ($_link->nodeValue) $channel['Link'] = $_link->nodeValue;
+ }
+ } else {
+ $channel['Link'] = $feed->link();
+ }
+ }
+ if ($author != null) {
+ $channel['Author'] = $author;
+ }
+ } elseif ($feed instanceof Zend_Feed_Atom) {
+ // Try get author
+ if ($feed->author()) {
+ if ($feed->author->name()) {
+ $author = $feed->author->name();
+ } else if ($feed->author->email()) {
+ $author = $feed->author->email();
+ } else {
+ $author = $feed->author();
+ }
+ } else {
+ $author = null;
+ }
+ // Loop over each entries and store relevant data
+ $counter = 0;
+ $channel['Entry'] = array();
+ foreach ($feed as $entry) {
+ if ($counter >= $numEntries) {
+ break;
+ }
+ $_entry = array();
+ $_entry['Title'] = $entry->title();
+ // get Link if rel="alternate"
+ if ($entry->link('alternate')) {
+ $_entry['Link'] = $entry->link('alternate');
+ } else {
+ // if there's no alternate, pick the one without "rel" attribtue
+ $_links = $entry->link;
+ if (is_array($_links)) {
+ foreach ($_links as $_link) {
+ if (empty($_link['rel'])) {
+ $_entry['Link'] = $_link['href'];
+ break;
+ }
+ }
+ } else {
+ $_entry['Link'] = $_links['href'];
+ }
+ }
+ if ($getSummaries && $entry->summary()) {
+ $_entry['Summary'] = $entry->summary();
+ }
+ $date = 0;
+ if ($entry->updated()) {
+ $date = strtotime($entry->updated());
+ } else {
+ if ($entry->published()) {
+ $date = strtotime($entry->published());
+ }
+ }
+ $_entry['Date'] = $date;
+ $channel['Entry'][] = $_entry;
+ // Remember author if first found
+ if (empty($author) && $entry->author()) {
+ if ($entry->author->name()) {
+ $author = $entry->author->name();
+ } else if ($entry->author->email()) {
+ $author = $entry->author->email();
+ } else {
+ $author = $entry->author();
+ }
+ } elseif (empty($author)) {
+ $author = null;
+ }
+ $counter ++;
+ }
+ $channel['Title'] = $feed->title();
+ $channel['URL'] = $url;
+ $channel['Description'] = $feed->subtitle();
+ // get Link if rel="alternate"
+ if ($feed->link('alternate')) {
+ $channel['Link'] = $feed->link('alternate');
+ } else {
+ // if there's no alternate, pick the one without "rel" attribtue
+ $_links = $feed->link;
+ if (is_array($_links)) {
+ foreach ($_links as $_link) {
+ if (empty($_link['rel'])) {
+ $channel['Link'] = $_link['href'];
+ break;
+ }
+ }
+ } else {
+ $channel['Link'] = $_links['href'];
+ }
+ }
+ if (! empty($author)) {
+ $channel['Author'] = $author;
+ }
+ } else {
+ throw new Exception('Invalid feed type');
+ }
+ $resp = json_encode($channel);
+ } catch (Zend_Feed_Exception $e) {
+ $resp = 'Error parsing feed: ' . $e->getMessage();
+ }
+ } else {
+ // feed import failed
+ $resp = "Error fetching feed, response code: " . $result->getHttpCode();
+ }
+ return $resp;
+ }
+}
Modified: incubator/shindig/trunk/php/src/gadgets/MetadataContext.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/MetadataContext.php?rev=744702&r1=744701&r2=744702&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/MetadataContext.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/MetadataContext.php Sun Feb 15 17:35:05 2009
@@ -24,7 +24,7 @@
parent::__construct('GADGET');
$this->url = $url;
$this->view = $jsonContext->view;
- $this->locale = new Locale($jsonContext->language, $jsonContext->country);
+ $this->locale = array('lang' => $jsonContext->language, 'country' => $jsonContext->country);
$this->container = $jsonContext->container;
}
Modified: incubator/shindig/trunk/php/src/gadgets/MetadataHandler.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/MetadataHandler.php?rev=744702&r1=744701&r2=744702&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/MetadataHandler.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/MetadataHandler.php Sun Feb 15 17:35:05 2009
@@ -27,12 +27,11 @@
$gadgetUrl = $gadget->url;
$gadgetModuleId = $gadget->moduleId;
$context = new MetadataGadgetContext($requests->context, $gadgetUrl);
- $gadgetServer = new GadgetServer();
- $gadget = $gadgetServer->processGadget($context);
+ $gadgetServer = new GadgetFactory($context, null);
+ $gadget = $gadgetServer->createGadget($gadgetUrl);
$response[] = $this->makeResponse($gadget, $gadgetModuleId, $gadgetUrl, $context);
} catch (Exception $e) {
- $response[] = array('errors' => array($e->getMessage()),
- 'moduleId' => $gadgetModuleId, 'url' => $gadgetUrl);
+ $response[] = array('errors' => array($e->getMessage()), 'moduleId' => $gadgetModuleId, 'url' => $gadgetUrl);
}
}
return $response;
@@ -40,46 +39,43 @@
private function makeResponse($gadget, $gadgetModuleId, $gadgetUrl, $context) {
$response = array();
+
$prefs = array();
- foreach ($gadget->getUserPrefs() as $pref) {
- $prefs[$pref->getName()] = array('displayName' => $pref->getDisplayName(),
- 'type' => $pref->getDataType(), 'default' => $pref->getDefaultValue(),
- 'enumValues' => $pref->getEnumValues(),
- 'required' => $pref->isRequired());
- }
- $features = array();
- foreach ($gadget->getRequires() as $feature) {
- $features[] = $feature->getName();
+ foreach ($gadget->gadgetSpec->userPrefs as $pref) {
+ $prefs[$pref['name']] = $pref;
}
+
$views = array();
- foreach ($gadget->getViews() as $view) {
+ foreach ($gadget->gadgetSpec->views as $name => $view) {
// we want to include all information, except for the content
- unset($view->content);
- $views[$view->getName()] = $view;
- }
- $links = array();
- foreach ($gadget->links as $link) {
- $links[] = $link;
- }
- $icons = array();
- foreach ($gadget->getIcons() as $icon) {
- $icons[] = $icon;
+ unset($view['content']);
+ $views[$name] = $view;
}
+
$oauth = array();
+
+ //FIXME missing from the spec parsing still
+ /*
$oauthspec = $gadget->getOAuthSpec();
if (! empty($oauthspec)) {
foreach ($oauthspec->getServices() as $oauthservice) {
- $oauth[$oauthservice->getName()] = array(
- "request" => $oauthservice->getRequestUrl(),
- "access" => $oauthservice->getAccessUrl(),
- "authorization" => $oauthservice->getAuthorizationUrl());
+ $oauth[$oauthservice->getName()] = array("request" => $oauthservice->getRequestUrl(), "access" => $oauthservice->getAccessUrl(), "authorization" => $oauthservice->getAuthorizationUrl());
}
}
+ */
+
+ //FIXME UrlGenerator needs fixin' still
+ //$response['iframeUrl'] = UrlGenerator::getIframeURL($gadget, $context);
+
+ $response['features'] = $gadget->features;
+ $response['links'] = $gadget->gadgetSpec->links;
+ $response['icons'] = $gadget->gadgetSpec->icon;
+ $response['views'] = $views;
+
$response['author'] = $gadget->getAuthor();
$response['authorEmail'] = $gadget->getAuthorEmail();
$response['description'] = $gadget->getDescription();
$response['directoryTitle'] = $gadget->getDirectoryTitle();
- $response['features'] = $features;
$response['screenshot'] = $gadget->getScreenShot();
$response['thumbnail'] = $gadget->getThumbnail();
$response['title'] = $gadget->getTitle();
@@ -98,12 +94,10 @@
$response['singleton'] = $gadget->getSingleton();
$response['scaling'] = $gadget->getScaling();
$response['scrolling'] = $gadget->getScrolling();
- $response['links'] = $links;
- $response['views'] = $views;
- $response['icons'] = $icons;
+
$response['moduleId'] = $gadgetModuleId;
$response['url'] = $gadgetUrl;
- $response['iframeUrl'] = UrlGenerator::getIframeURL($gadget, $context);
+
$response['userPrefs'] = $prefs;
$response['oauth'] = $oauth;
return $response;
Added: incubator/shindig/trunk/php/src/gadgets/ProxyBase.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/ProxyBase.php?rev=744702&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/ProxyBase.php (added)
+++ incubator/shindig/trunk/php/src/gadgets/ProxyBase.php Sun Feb 15 17:35:05 2009
@@ -0,0 +1,151 @@
+<?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.
+ */
+
+/**
+ * This class contains the shared methods between the Proxy and makeRequest handlers
+ */
+class ProxyBase {
+ public $context;
+ protected $disallowedHeaders = array('Keep-Alive', 'Host', 'Accept-Encoding', 'Set-Cookie', 'Content-Length', 'Content-Encoding', 'ETag', 'Last-Modified', 'Accept-Ranges', 'Vary', 'Expires', 'Date', 'Pragma', 'Cache-Control', 'Transfer-Encoding');
+
+ public function __construct($context) {
+ $this->context = $context;
+ }
+
+ /**
+ * Retrieves the actual content
+ *
+ * @param string $url the url to fetch
+ * @return the filled in request (RemoteContentRequest)
+ */
+ protected function fetchContent($url, $method = 'GET') {
+ // Check the protocol requested - curl doesn't really support file://
+ // requests but the 'error' should be handled properly
+ $protocolSplit = explode('://', $url, 2);
+ if (count($protocolSplit) < 2) {
+ throw new Exception("Invalid protocol specified");
+ } else {
+ $protocol = strtoupper($protocolSplit[0]);
+ if ($protocol != "HTTP" && $protocol != "HTTPS") {
+ throw new Exception("Invalid protocol specified in url: " . htmlentities($protocol));
+ }
+ }
+ $headers = '';
+ $requestHeaders = $this->request_headers();
+ foreach ($requestHeaders as $key => $val) {
+ $key = str_replace(' ', '-', ucwords(str_replace('-', ' ', $key))); // force the header name to have the proper Header-Name casing
+ if (! in_array($key, $this->disallowedHeaders)) {
+ // propper curl header format according to http://www.php.net/manual/en/function.curl-setopt.php#80099
+ $headers .= "$key: $val\n";
+ }
+ }
+ if ($method == 'POST') {
+ $data = isset($_GET['postData']) ? $_GET['postData'] : false;
+ if (! $data) {
+ $data = isset($_POST['postData']) ? $_POST['postData'] : false;
+ }
+ $postData = '';
+ if ($data) {
+ $data = urldecode($data);
+ $entries = explode('&', $data);
+ foreach ($entries as $entry) {
+ $parts = explode('=', $entry);
+ // Process only if its a valid value=something pair
+ if (count($parts) == 2) {
+ $postData .= urlencode($parts[0]) . '=' . urlencode($parts[1]) . '&';
+ }
+ }
+ // chop of the trailing &
+ if (strlen($postData)) {
+ $postData = substr($postData, 0, strlen($postData) - 1);
+ }
+ }
+ // even if postData is an empty string, it will still post (since RemoteContentRquest checks if its false)
+ // so the request to POST is still honored
+ $request = new RemoteContentRequest($url, $headers, $postData);
+ $request = $this->context->getHttpFetcher()->fetch($request, $this->context);
+ } else {
+ $request = new RemoteContentRequest($url, $headers);
+ $request = $this->context->getHttpFetcher()->fetch($request, $this->context);
+ }
+ return $request;
+ }
+
+ /**
+ * Sets the caching (Cache-Control & Expires) with a cache age of $lastModified
+ * or if $lastModified === false, sets Pragma: no-cache & Cache-Control: no-cache
+ */
+ protected function setCachingHeaders($lastModified = false) {
+ $maxAge = $this->context->getIgnoreCache() ? false : $this->context->getRefreshInterval();
+ if ($maxAge) {
+ if ($lastModified) {
+ header("Last-Modified: $lastModified");
+ }
+ // time() is a kernel call, so lets avoid it and use the request time instead
+ $time = $_SERVER['REQUEST_TIME'];
+ $expires = $maxAge !== false ? $time + $maxAge : $time - 3000;
+ $public = $maxAge ? 'public' : 'private';
+ $maxAge = $maxAge === false ? '0' : $maxAge;
+ header("Cache-Control: {$public}; max-age={$maxAge}", true);
+ header("Expires: " . gmdate("D, d M Y H:i:s", $expires) . " GMT", true);
+ } else {
+ header("Cache-Control: no-cache", true);
+ header("Pragma: no-cache", true);
+ }
+ }
+
+ /**
+ * Does a quick-and-dirty url validation
+ *
+ * @param string $url
+ * @return string the 'validated' url
+ */
+ protected function validateUrl($url) {
+ if (! @parse_url($url)) {
+ throw new Exception("Invalid Url");
+ } else {
+ return $url;
+ }
+ }
+
+ /**
+ * Returns the request headers, using the apache_request_headers function if it's
+ * available, and otherwise tries to guess them from the $_SERVER superglobal
+ *
+ * @return unknown
+ */
+ protected function request_headers() {
+ // Try to use apache's request headers if available
+ if (function_exists("apache_request_headers")) {
+ if (($headers = apache_request_headers())) {
+ return $headers;
+ }
+ }
+ // if that failed, try to create them from the _SERVER superglobal
+ $headers = array();
+ foreach (array_keys($_SERVER) as $skey) {
+ if (substr($skey, 0, 5) == "HTTP_") {
+ $headername = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($skey, 0, 5)))));
+ $headers[$headername] = $_SERVER[$skey];
+ }
+ }
+ return $headers;
+ }
+}
Modified: incubator/shindig/trunk/php/src/gadgets/ProxyHandler.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/ProxyHandler.php?rev=744702&r1=744701&r2=744702&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/ProxyHandler.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/ProxyHandler.php Sun Feb 15 17:35:05 2009
@@ -24,252 +24,20 @@
/**
* The ProxyHandler class does the actual proxy'ing work. it deals both with
* GET and POST based input, and peforms a request based on the input, headers and
- * httpmethod params. It also deals with request signing and verification thru the
- * authz and st (security token) params.
+ * httpmethod params.
*
*/
-class ProxyHandler {
- private $context;
- private $signingFetcher;
- private $oauthFetcher;
-
- public function __construct($context, $signingFetcher = null, $oauthFetcher = null) {
- $this->context = $context;
- $this->signingFetcher = $signingFetcher;
- $this->oauthFetcher = $oauthFetcher;
- }
-
- /**
- * Fetches content and returns it in JSON format
- *
- * @param string $url the url to fetch
- * @param GadgetSigner $signer the request signer to use
- * @param string $method the http method to use (get or post) in making the request
- */
- public function fetchJson($url, $signer, $method) {
- try {
- $token = $this->context->extractAndValidateToken($signer);
- } catch (Exception $e) {
- $token = '';
- // no token given, safe to ignore
- }
- $url = $this->validateUrl($url);
- // Fetch the content and convert it into JSON.
- // TODO: Fetcher needs to handle variety of HTTP methods.
- $result = $this->fetchContentDivert($url, $method, $signer);
- if (! isset($result)) {
- //OAuthFetcher only
- $metadata = $this->oauthFetcher->getResponseMetadata();
- $json = array($url => $metadata);
- $json = json_encode($json);
- $output = UNPARSEABLE_CRUFT . $json;
- $this->setCachingHeaders();
- header("Content-Type: application/json; charset=utf-8", true);
- echo $output;
- die();
- }
- $status = (int)$result->getHttpCode();
- //header("HTTP/1.1 $status", true);
- if ($status == 200) {
- $output = '';
- if (isset($_REQUEST['contentType']) && $_REQUEST['contentType'] == 'FEED') {
- require 'external/Zend/Feed.php';
- $numEntries = $_REQUEST['numEntries'];
- $getSummaries = ! empty($_REQUEST['getSummaries']) && $_REQUEST['getSummaries'] != 'false' ? true : false;
- $channel = array();
- $request = new RemoteContentRequest($url);
- $request = $this->context->getHttpFetcher()->fetch($request, $this->context);
- if ((int)$result->getHttpCode() == 200) {
- $content = $result->getResponseContent();
- try {
- $feed = Zend_Feed::importString($content);
- if ($feed instanceof Zend_Feed_Rss) {
- // Try get author
- if ($feed->author()) {
- $author = $feed->author();
- } else {
- if ($feed->creator()) {
- $author = $feed->creator();
- } else {
- $author = null;
- }
- }
- // Loop over each channel item and store relevant data
- $counter = 0;
- $channel['Entry'] = array();
- foreach ($feed as $item) {
- if ($counter >= $numEntries) {
- break;
- }
- $_entry = array();
- $_entry['Title'] = $item->title();
- $_entry['Link'] = $item->link();
- if ($getSummaries && $item->description()) {
- $_entry['Summary'] = $item->description();
- }
- $date = 0;
- if ($item->date()) {
- $date = strtotime($item->date());
- } else {
- if ($item->pubDate()) {
- $date = strtotime($item->pubDate());
- }
- }
- $_entry['Date'] = $date;
- $channel['Entry'][] = $_entry;
- // Remember author if first found
- if (empty($author) && $item->author()) {
- $author = $item->author();
- } else if ($item->creator()) {
- $author = $item->creator();
- }
- $counter ++;
- }
- $channel['Title'] = $feed->title();
- $channel['URL'] = $url;
- $channel['Description'] = $feed->description();
- if ($feed->link()) {
- if (is_array($feed->link())) {
- foreach ($feed->link() as $_link) {
- if ($_link->nodeValue) $channel['Link'] = $_link->nodeValue;
- }
- } else {
- $channel['Link'] = $feed->link();
- }
- }
- if ($author != null) {
- $channel['Author'] = $author;
- }
- } elseif ($feed instanceof Zend_Feed_Atom) {
- // Try get author
- if ($feed->author()) {
- if ($feed->author->name()) {
- $author = $feed->author->name();
- } else if ($feed->author->email()) {
- $author = $feed->author->email();
- } else {
- $author = $feed->author();
- }
- } else {
- $author = null;
- }
- // Loop over each entries and store relevant data
- $counter = 0;
- $channel['Entry'] = array();
- foreach ($feed as $entry) {
- if ($counter >= $numEntries) {
- break;
- }
- $_entry = array();
- $_entry['Title'] = $entry->title();
- // get Link if rel="alternate"
- if ($entry->link('alternate')) {
- $_entry['Link'] = $entry->link('alternate');
- } else {
- // if there's no alternate, pick the one without "rel" attribtue
- $_links = $entry->link;
- if (is_array($_links)) {
- foreach ($_links as $_link) {
- if (empty($_link['rel'])) {
- $_entry['Link'] = $_link['href'];
- break;
- }
- }
- } else {
- $_entry['Link'] = $_links['href'];
- }
- }
- if ($getSummaries && $entry->summary()) {
- $_entry['Summary'] = $entry->summary();
- }
- $date = 0;
- if ($entry->updated()) {
- $date = strtotime($entry->updated());
- } else {
- if ($entry->published()) {
- $date = strtotime($entry->published());
- }
- }
- $_entry['Date'] = $date;
- $channel['Entry'][] = $_entry;
- // Remember author if first found
- if (empty($author) && $entry->author()) {
- if ($entry->author->name()) {
- $author = $entry->author->name();
- } else if ($entry->author->email()) {
- $author = $entry->author->email();
- } else {
- $author = $entry->author();
- }
- } elseif (empty($author)) {
- $author = null;
- }
- $counter ++;
- }
- $channel['Title'] = $feed->title();
- $channel['URL'] = $url;
- $channel['Description'] = $feed->subtitle();
- // get Link if rel="alternate"
- if ($feed->link('alternate')) {
- $channel['Link'] = $feed->link('alternate');
- } else {
- // if there's no alternate, pick the one without "rel" attribtue
- $_links = $feed->link;
- if (is_array($_links)) {
- foreach ($_links as $_link) {
- if (empty($_link['rel'])) {
- $channel['Link'] = $_link['href'];
- break;
- }
- }
- } else {
- $channel['Link'] = $_links['href'];
- }
- }
- if (! empty($author)) {
- $channel['Author'] = $author;
- }
- } else {
- throw new Exception('Invalid feed type');
- }
- $resp = json_encode($channel);
- } catch (Zend_Feed_Exception $e) {
- $resp = 'Error parsing feed: ' . $e->getMessage();
- }
- } else {
- // feed import failed
- $resp = "Error fetching feed, response code: " . $result->getHttpCode();
- }
- } else {
- $resp = $result->getResponseContent();
- }
- $json = array($url => array('body' => $resp, 'rc' => $status));
- $json = json_encode($json);
- $output = UNPARSEABLE_CRUFT . $json;
- $this->setCachingHeaders();
- // header("Content-Type: application/json; charset=utf-8", true);
- echo $output;
- } else {
- @ob_end_clean();
- header("HTTP/1.0 404 Not Found", true);
- echo "<html><body><h1>404 - Not Found</h1></body></html>";
- }
- die();
- }
+class ProxyHandler extends ProxyBase {
/**
* Fetches the content and returns it as-is using the headers as returned
* by the remote host.
*
* @param string $url the url to retrieve
- * @param GadgetSigner $signer the GadgetSigner to use
- * @param string $method either get or post
*/
- public function fetch($url, $signer, $method) {
+ public function fetch($url) {
$url = $this->validateUrl($url);
- //TODO: Fetcher needs to handle variety of HTTP methods.
- $result = $this->fetchContent($url, $method);
- // TODO: Fetcher needs to handle variety of HTTP methods.
+ $result = $this->fetchContent($url, 'GET');
$status = (int)$result->getHttpCode();
if ($status == 200) {
$headers = explode("\n", $result->getResponseHeaders());
@@ -277,12 +45,14 @@
foreach ($headers as $header) {
if (strpos($header, ':')) {
$key = trim(substr($header, 0, strpos($header, ':')));
+ $key = str_replace(' ', '-', ucwords(str_replace('-', ' ', $key))); // force the header name to have the proper Header-Name casing
$val = trim(substr($header, strpos($header, ':') + 1));
// filter out headers that would otherwise mess up our output
- if (strcasecmp($key, "Transfer-Encoding") != 0 && strcasecmp($key, "Cache-Control") != 0 && strcasecmp($key, "Expires") != 0 && strcasecmp($key, "Content-Length") != 0 && strcasecmp($key, "ETag") != 0) {
- header("$key: $val");
+ if (! in_array($key, $this->disallowedHeaders)) {
+ header("$key: $val", true);
+ } else {
}
- if ($key == 'Content-Type' && $val == 'application/x-shockwave-flash') {
+ if ($key == 'Content-Type' && strtolower($val) == 'application/x-shockwave-flash') {
// We're skipping the content disposition header for flash due to an issue with Flash player 10
// This does make some sites a higher value phishing target, but this can be mitigated by
// additional referer checks.
@@ -290,28 +60,21 @@
}
}
}
- if (!$isShockwaveFlash) {
+ if (! $isShockwaveFlash) {
header('Content-Disposition: attachment;filename=p.txt');
}
- $etag = md5($result->getResponseContent());
$lastModified = $result->getResponseHeader('Last-Modified') != null ? $result->getResponseHeader('Last-Modified') : gmdate('D, d M Y H:i:s', $result->getCreated()) . ' GMT';
$notModified = false;
- // If HTTP_PRAGMA | HTTP_CACHE_CONTROL == no-cache, the browser wants to do a 'forced reload'
- if (! isset($_SERVER['HTTP_PRAGMA']) || ! strstr(strtolower($_SERVER['HTTP_PRAGMA']), 'no-cache') && (! isset($_SERVER['HTTP_CACHE_CONTROL']) || ! strstr(strtolower($_SERVER['HTTP_CACHE_CONTROL']), 'no-cache'))) {
- if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag) {
- // if e-tag's match, set not modified, and no need to check the if-modified-since headers
+ if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $lastModified && ! isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
+ $if_modified_since = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
+ // Use the request's Last-Modified, otherwise fall back on our internal time keeping (the time the request was created)
+ $lastModified = strtotime($lastModified);
+ if ($lastModified <= $if_modified_since) {
$notModified = true;
- } elseif (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $lastModified && ! isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
- $if_modified_since = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']);
- // Use the request's Last-Modified, otherwise fall back on our internal time keeping (the time the request was created)
- $lastModified = strtotime($lastModified);
- if ($lastModified <= $if_modified_since) {
- $notModified = true;
- }
}
}
- $this->setCachingHeaders($etag, $this->context->getRefreshInterval(), $lastModified);
- // If the cached file time is within the refreshInterval params value and the ETag match, return not-modified
+ $this->setCachingHeaders($lastModified);
+ // If the cached file time is within the refreshInterval params value, return not-modified
if ($notModified) {
header('HTTP/1.0 304 Not Modified', true);
header('Content-Length: 0', true);
@@ -325,150 +88,5 @@
echo "<html><body><h1>404 - Not Found ($status)</h1>";
echo "</body></html>";
}
- // make sure the HttpServlet destructor doesn't override ours
- die();
- }
-
- /**
- * Both fetch and fetchJson call this function to retrieve the actual content
- *
- * @param string $url the url to fetch
- * @param string $method either get or post
- * @return the filled in request (RemoteContentRequest)
- */
- private function fetchContent($url, $method) {
- //TODO get actual character encoding from the request
-
- // Check the protocol requested - curl doesn't really support file://
- // requests but the 'error' should be handled properly
- $protocolSplit = explode('://', $url, 2);
- if (count($protocolSplit) < 2) {
- throw new Exception("Invalid protocol specified");
- } else {
- $protocol = strtoupper($protocolSplit[0]);
- if ($protocol != "HTTP" && $protocol != "HTTPS" && $protocol != "FTP") {
- throw new Exception("Invalid protocol specified in url ($protocol)");
- }
- }
-
- // Extract the request headers from the $_SERVER super-global (this -does- unfortunatly mean that any header that php doesn't understand won't be proxied thru though)
- // if this turns out to be a problem we could add support for HTTP_RAW_HEADERS, but this depends on a php.ini setting, so i'd rather prevent that from being required
- $headers = '';
- $context = new GadgetContext('GADGET');
- $requestHeaders = $this->request_headers();
- foreach ($requestHeaders as $key => $val) {
- if ($key != 'Keep-alive' && $key != 'Connection' && $key != 'Host' && $key != 'Accept' && $key != 'Accept-Encoding') {
- // propper curl header format according to http://www.php.net/manual/en/function.curl-setopt.php#80099
- $headers .= "$key: $val\n";
- }
- }
- if ($method == 'POST') {
- $data = isset($_GET['postData']) ? $_GET['postData'] : false;
- if (! $data) {
- $data = isset($_POST['postData']) ? $_POST['postData'] : false;
- }
- $postData = '';
- if ($data) {
- $data = urldecode($data);
- $entries = explode('&', $data);
- foreach ($entries as $entry) {
- $parts = explode('=', $entry);
- // Process only if its a valid value=something pair
- if (count($parts) == 2) {
- $postData .= urlencode($parts[0]) . '=' . urlencode($parts[1]) . '&';
- }
- }
- // chop of the trailing &
- if (strlen($postData)) {
- $postData = substr($postData, 0, strlen($postData) - 1);
- }
- }
- // even if postData is an empty string, it will still post (since RemoteContentRquest checks if its false)
- // so the request to POST is still honored
- $request = new RemoteContentRequest($url, $headers, $postData);
- $request = $this->context->getHttpFetcher()->fetch($request, $context);
- } else {
- $request = new RemoteContentRequest($url, $headers);
- $request = $this->context->getHttpFetcher()->fetch($request, $context);
- }
- return $request;
- }
-
- private function fetchContentDivert($url, $method, $signer) {
- $authz = isset($_GET['authz']) ? $_GET['authz'] : (isset($_POST['authz']) ? $_POST['authz'] : '');
- $token = $this->context->extractAndValidateToken($signer);
- switch (strtoupper($authz)) {
- case 'SIGNED':
- $fetcher = $this->signingFetcher->getSigningFetcher(new BasicRemoteContentFetcher(), $token);
- return $fetcher->fetch($url, $method);
- case 'OAUTH':
- $params = new OAuthRequestParams();
- $fetcher = $this->signingFetcher->getSigningFetcher(new BasicRemoteContentFetcher(), $token);
- $oAuthFetcherFactory = new OAuthFetcherFactory($fetcher);
- $this->oauthFetcher = $oAuthFetcherFactory->getOAuthFetcher($fetcher, $token, $params);
- $request = new RemoteContentRequest($url);
- $request->createRemoteContentRequestWithUri($url);
- return $this->oauthFetcher->fetch($request);
- case 'NONE':
- default:
- return $this->fetchContent($url, $method);
- }
- }
-
- public function setContentFetcher($contentFetcherFactory) {
- $this->contentFetcherFactory = $contentFetcherFactory;
- }
-
- /**
- * Sets the caching headers (overwriting anything the remote host set) to force
- * the browser not to cache this.
- *
- */
- private function setCachingHeaders($etag = false, $maxAge = false, $lastModified = false) {
- if ($etag) {
- header("ETag: $etag");
- }
- if ($lastModified) {
- header("Last-Modified: $lastModified");
- }
- $expires = $maxAge !== false ? time() + $maxAge : time() - 3000;
- $public = $maxAge ? 'public' : 'private';
- $maxAge = $maxAge === false ? '0' : $maxAge;
- header("Cache-Control: {$public}; max-age={$maxAge}", true);
- header("Expires: " . gmdate("D, d M Y H:i:s", $expires) . " GMT", true);
- }
-
- /**
- * Empty function, should make something practical here some day.
- * it's function should be to validate the given url if its in
- * correct http(s):port://location/url format
- *
- * @param string $url
- * @return string the 'validated' url
- */
- private function validateUrl($url) {
- if (! @parse_url($url)) {
- throw new Exception("Invalid Url");
- } else {
- return $url;
- }
- }
-
- private function request_headers() {
- // Try to use apache's request headers if available
- if (function_exists("apache_request_headers")) {
- if (($headers = apache_request_headers())) {
- return $headers;
- }
- }
- // if that failed, try to create them from the _SERVER superglobal
- $headers = array();
- foreach (array_keys($_SERVER) as $skey) {
- if (substr($skey, 0, 5) == "HTTP_") {
- $headername = str_replace(" ", "-", ucwords(strtolower(str_replace("_", " ", substr($skey, 0, 5)))));
- $headers[$headername] = $_SERVER[$skey];
- }
- }
- return $headers;
}
}
Added: incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php?rev=744702&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php (added)
+++ incubator/shindig/trunk/php/src/gadgets/render/GadgetHrefRenderer.php Sun Feb 15 17:35:05 2009
@@ -0,0 +1,25 @@
+<?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.
+ */
+
+class GadgetHrefRenderer extends GadgetRenderer {
+ public function renderGadget(Gadget $gadget, $view) {
+ echo "render href";
+ }
+}
Added: incubator/shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php?rev=744702&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php (added)
+++ incubator/shindig/trunk/php/src/gadgets/render/GadgetHtmlRenderer.php Sun Feb 15 17:35:05 2009
@@ -0,0 +1,149 @@
+<?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.
+ */
+
+class EmptyClass {
+}
+
+/**
+ * Renders a Gadget's Content type="html" view, inlining the content, feature javascript and javascript initialization
+ * into the gadget's content
+ *
+ */
+class GadgetHtmlRenderer extends GadgetRenderer {
+
+ public function renderGadget(Gadget $gadget, $view) {
+
+ // Was a privacy policy header configured? if so set it
+ if (Config::get('P3P') != '') {
+ header("P3P: " . Config::get('P3P'));
+ }
+
+ $content = '';
+ // Set doctype if quirks = false or empty in the view
+ if (! empty($view['quirks']) || ! $view['quirks']) {
+ $content .= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n";
+ }
+ $content .= "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><style type=\"text/css\">" . Config::get('gadget_css') . "</style></head><body>\n";
+
+ // Inject the OpenSocial feature javascripts
+ $forcedJsLibs = $this->getForcedJsLibs();
+ if (! empty($forcedJsLibs)) {
+ // if some of the feature libraries are externalized (through a browser cachable <script src="/gadgets/js/opensocial-0.9:settitle.js"> type url)
+ // we inject the tag and don't inline those libs (and their dependencies)
+ $forcedJsLibs = explode(':', $forcedJsLibs);
+ $content .= sprintf("<script src=\"%s\"></script>\n", Config::get('default_js_prefix') . $this->getJsUrl($forcedJsLibs, $gadget) . "&container=" . $this->context->getContainer()) . "\n";
+ $registry = $this->context->getRegistry();
+ $missing = array();
+ $registry->resolveFeatures($forcedJsLibs, $forcedJsLibs, $missing);
+ }
+ $content .= "<script>\n";
+ foreach ($gadget->features as $feature) {
+ if (! count($forcedJsLibs) || ! in_array($feature, $forcedJsLibs)) {
+ $content .= $this->context->getRegistry()->getFeatureContent($feature, $this->context, true);
+ }
+ }
+
+ // Add the JavaScript initialization strings for the configuration, localization and preloads
+ $content .= $this->appendJsConfig($gadget, count($forcedJsLibs));
+ $content .= $this->appendMessages($gadget);
+ $content .= $this->appendPreloads($gadget);
+ $content .= "</script>";
+
+ // Append the content from the view
+ $content .= $gadget->substitutions->substitute($view['content']);
+
+ // And add our runOnLoadHandlers() call
+ $content .= "\n<script>gadgets.util.runOnLoadHandlers();</script></body>\n</html>";
+ echo $content;
+ }
+
+ /**
+ * Retrieve the forced javascript libraries (if any), using either the &libs= from the query
+ * or if that's empty, from the config
+ *
+ * @return unknown
+ */
+ private function getForcedJsLibs() {
+ $forcedJsLibs = $this->context->getForcedJsLibs();
+ // allow the &libs=.. param to override our forced js libs configuration value
+ if (empty($forcedJsLibs)) {
+ $forcedJsLibs = Config::get('focedJsLibs');
+ }
+ return $forcedJsLibs;
+ }
+
+ /**
+ * Appends the javascript features configuration string
+ *
+ * @param Gadget $gadget
+ * @param unknown_type $hasForcedLibs
+ * @return string
+ */
+ private function appendJsConfig(Gadget $gadget, $hasForcedLibs) {
+ $container = $this->context->getContainer();
+ $containerConfig = $this->context->getContainerConfig();
+ //TODO some day we should parse the forcedLibs too, and include their config selectivly as well for now we just include everything if forced libs is set.
+ if ($hasForcedLibs) {
+ $gadgetConfig = $containerConfig->getConfig($container, 'gadgets.features');
+ } else {
+ $gadgetConfig = array();
+ $featureConfig = $containerConfig->getConfig($container, 'gadgets.features');
+ foreach ($gadget->getJsLibraries() as $library) {
+ $feature = $library->getFeatureName();
+ if (! isset($gadgetConfig[$feature]) && ! empty($featureConfig[$feature])) {
+ $gadgetConfig[$feature] = $featureConfig[$feature];
+ }
+ }
+ }
+ // Add gadgets.util support. This is calculated dynamically based on request inputs.
+ // See java/org/apache/shindig/gadgets/render/RenderingContentRewriter.java for reference.
+ $requires = array();
+ foreach ($gadget->features as $feature) {
+ $requires[$feature] = new EmptyClass();
+ }
+ $gadgetConfig['core.util'] = $requires;
+ return "gadgets.config.init(" . json_encode($gadgetConfig) . ");\n";
+ }
+
+ /**
+ * Injects the relevant translation message bundle into the javascript api
+ *
+ * @param Gadget $gadget
+ * @return string
+ */
+ private function appendMessages(Gadget $gadget) {
+ $msgs = '';
+ if (! empty($gadget->gadgetSpec->locales)) {
+ $msgs = json_encode($gadget->gadgetSpec->locales);
+ }
+ return "gadgets.Prefs.setMessages_($msgs);\n";
+ }
+
+ /**
+ * Injects the preloaded content into the javascript api
+ *
+ * @param Gadget $gadget
+ * @return string
+ */
+ private function appendPreloads(Gadget $gadget) {
+ return "gadgets.io.preloaded_ = " . (count($gadget->gadgetSpec->preloads) ? json_encode($gadget->gadgetSpec->preloads) : "{}") . ";\n";
+ }
+}
Added: incubator/shindig/trunk/php/src/gadgets/render/GadgetRenderer.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/render/GadgetRenderer.php?rev=744702&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/render/GadgetRenderer.php (added)
+++ incubator/shindig/trunk/php/src/gadgets/render/GadgetRenderer.php Sun Feb 15 17:35:05 2009
@@ -0,0 +1,63 @@
+<?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 GadgetRenderer {
+ protected $context;
+
+ public function __construct(GadgetContext $context) {
+ $this->context = $context;
+ }
+
+ /**
+ * generates the library string (core:caja:etc.js) including a checksum of all the
+ * javascript content (?v=<md5 of js>) for cache busting
+ *
+ * @param string $libs
+ * @param Gadget $gadget
+ * @return string the list of libraries in core:caja:etc.js?v=checksum> format
+ */
+ protected function getJsUrl($features) {
+ $ret = '';
+ if (! is_array($features) || ! count($features)) {
+ $ret = 'core';
+ } else {
+ $ret = implode(':', $features);
+ }
+ $cache = Config::get('feature_cache');
+ $cache = new $cache();
+ if (($md5 = $cache->get(md5('getJsUrlMD5'))) === false) {
+ $registry = $this->context->getRegistry();
+ $features = $registry->features;
+
+ // Build a version string from the md5() checksum of all included javascript
+ // to ensure the client always has the right version
+ $inlineJs = '';
+ foreach ($features as $feature => $content) {
+ $inlineJs .= $registry->getFeatureContent($feature, $this->context, true);
+ }
+ $md5 = md5($inlineJs);
+ $cache->set(md5('getJsUrlMD5'), $md5);
+ }
+ $ret .= ".js?v=" . $md5;
+ return $ret;
+ }
+
+ abstract function renderGadget(Gadget $gadget, $view);
+}
\ No newline at end of file
Added: incubator/shindig/trunk/php/src/gadgets/render/GadgetUrlRenderer.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/render/GadgetUrlRenderer.php?rev=744702&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/render/GadgetUrlRenderer.php (added)
+++ incubator/shindig/trunk/php/src/gadgets/render/GadgetUrlRenderer.php Sun Feb 15 17:35:05 2009
@@ -0,0 +1,90 @@
+<?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.
+ */
+
+class GadgetUrlRenderer extends GadgetRenderer {
+
+ /**
+ * Renders an 'URL' type view (where the iframe is redirected to the specified url)
+ * This is more a legacy iGoogle support feature then something that should be actually
+ * used. Proxied content is the socially aware (and higher performance) version of this
+ * See GadgetHrefRenderer for it's implementation.
+ *
+ * @param Gadget $gadget
+ * @param Array $view
+ */
+ public function renderGadget(Gadget $gadget, $view) {
+ // Preserve existing query string parameters.
+ $redirURI = $view['href'];
+ $queryStr = strpos($redirURI, '?') !== false ? substr($redirURI, strpos($redirURI, '?')) : '';
+ $query = $queryStr;
+ $query .= $this->getPrefsQueryString($gadget->gadgetSpec->userPrefs);
+ $features = array();
+ $forcedLibs = Config::get('focedJsLibs');
+ if ($forcedLibs == null) {
+ $features = $gadget->features;
+ } else {
+ $features = explode(':', $forcedLibs);
+ }
+ $query .= $this->appendLibsToQuery($features);
+ // code bugs out with me because of the invalid url syntax since we dont have a URI class to fix it for us
+ // this works around that
+ if (substr($query, 0, 1) == '&') {
+ $query = '?' . substr($query, 1);
+ }
+ $redirURI .= $query;
+ header('Location: ' . $redirURI);
+ }
+
+ /**
+ * Returns the requested libs (from getjsUrl) with the libs_param_name prepended
+ * ie: in libs=core:caja:etc.js format
+ *
+ * @param string $libs the libraries
+ * @param Gadget $gadget
+ * @return string the libs=... string to append to the redirection url
+ */
+ private function appendLibsToQuery($features) {
+ $ret = "&";
+ $ret .= Config::get('libs_param_name');
+ $ret .= "=";
+ $ret .= str_replace('?', '&', $this->getJsUrl($features));
+ return $ret;
+ }
+
+ /**
+ * Returns the user preferences in &up_<name>=<val> format
+ *
+ * @param array $libs array of features this gadget requires
+ * @param Gadget $gadget
+ * @return string the up_<name>=<val> string to use in the redirection url
+ */
+ private function getPrefsQueryString($prefs) {
+ $ret = '';
+ foreach ($prefs as $pref) {
+ $ret .= '&';
+ $ret .= Config::get('userpref_param_prefix');
+ $ret .= urlencode($pref['name']);
+ $ret .= '=';
+ $ret .= urlencode($pref['value']);
+ }
+ return $ret;
+ }
+}
Modified: incubator/shindig/trunk/php/src/gadgets/servlet/GadgetRenderingServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/servlet/GadgetRenderingServlet.php?rev=744702&r1=744701&r2=744702&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/servlet/GadgetRenderingServlet.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/servlet/GadgetRenderingServlet.php Sun Feb 15 17:35:05 2009
@@ -18,131 +18,76 @@
* under the License.
*/
-require 'src/common/HttpServlet.php';
-require 'src/gadgets/GadgetContext.php';
-require 'src/gadgets/GadgetServer.php';
-require 'src/common/RemoteContentRequest.php';
-require 'src/common/RemoteContent.php';
-require 'src/common/Cache.php';
-require 'src/common/RemoteContentFetcher.php';
-require 'src/gadgets/GadgetSpecParser.php';
-require 'src/gadgets/Gadget.php';
-require 'src/gadgets/GadgetId.php';
-require 'src/gadgets/UserPrefs.php';
-require 'src/gadgets/Substitutions.php';
-require 'src/gadgets/LocaleSpec.php';
-require 'src/gadgets/LocaleMessageBundle.php';
-require 'src/gadgets/GadgetBlacklist.php';
-require 'src/common/Locale.php';
-require 'src/gadgets/UserPref.php';
-require 'src/gadgets/ViewSpec.php';
-require 'src/gadgets/FeatureSpec.php';
-require 'src/gadgets/MessageBundleParser.php';
-require 'src/gadgets/MessageBundle.php';
-require 'src/gadgets/GadgetFeatureRegistry.php';
-require 'src/gadgets/GadgetFeatureFactory.php';
-require 'src/gadgets/GadgetFeature.php';
-require 'src/gadgets/JsLibraryFeatureFactory.php';
-require 'src/gadgets/JsLibrary.php';
-require 'src/gadgets/HttpUtil.php';
-require 'src/gadgets/ContainerConfig.php';
-require 'src/common/JsMin.php';
-require 'src/common/SecurityTokenDecoder.php';
-require 'src/common/SecurityToken.php';
-require 'src/common/BlobCrypter.php';
-require 'src/gadgets/rewrite/ContentRewriter.php';
-require 'src/gadgets/rewrite/ContentRewriteFeature.php';
+require_once 'src/common/HttpServlet.php';
+require_once 'src/common/JsMin.php';
+require_once 'src/common/SecurityTokenDecoder.php';
+require_once 'src/common/SecurityToken.php';
+require_once 'src/common/BlobCrypter.php';
+require_once 'src/common/RemoteContentRequest.php';
+require_once 'src/common/RemoteContent.php';
+require_once 'src/common/Cache.php';
+require_once 'src/common/RemoteContentFetcher.php';
+require_once 'src/common/sample/BasicRemoteContent.php';
+require_once 'src/common/sample/BasicRemoteContentFetcher.php';
+require_once 'src/gadgets/GadgetSpecParser.php';
+require_once 'src/gadgets/GadgetBlacklist.php';
+require_once 'src/gadgets/sample/BasicGadgetBlacklist.php';
+require_once 'src/gadgets/GadgetContext.php';
+require_once 'src/gadgets/GadgetFactory.php';
+require_once 'src/gadgets/GadgetSpec.php';
+require_once 'src/gadgets/Gadget.php';
+require_once 'src/gadgets/render/GadgetRenderer.php';
-/**
- * This class deals with the gadget rendering requests (in default config this
- * would be /gadgets/ifr?url=<some gadget's url>). It uses the gadget server and
- * gadget context to render the xml to a valid html file, and outputs it.
- *
- */
class GadgetRenderingServlet extends HttpServlet {
private $context;
- /**
- * Creates the gadget using the GadgetServer class and calls outputGadget
- *
- */
public function doGet() {
try {
if (empty($_GET['url'])) {
throw new GadgetException("Missing required parameter: url");
}
- // GadgetContext builds up all the contextual variables (based on the url or post)
- // plus instances all required classes (feature registry, fetcher, blacklist, etc)
$this->context = new GadgetContext('GADGET');
- // Unfortunatly we can't do caja content filtering here, hoping we'll have a RPC service
- // or command line caja to use for this at some point
- $gadgetServer = new GadgetServer();
- $gadget = $gadgetServer->processGadget($this->context);
- $this->outputGadget($gadget, $this->context);
+ $gadgetSigner = Config::get('security_token_signer');
+ $gadgetSigner = new $gadgetSigner();
+ try {
+ $token = $this->context->extractAndValidateToken($gadgetSigner);
+ } catch (Exception $e) {
+ // no token given, this is a fatal error if 'render_token_required' is set to true
+ if (Config::get('render_token_required')) {
+ $this->showError($e);
+ } else {
+ $token = '';
+ }
+ }
+ $gadgetSpecFactory = new GadgetFactory($this->context, $token);
+ $gadget = $gadgetSpecFactory->createGadget();
+ $this->setCachingHeaders();
+ $this->renderGadget($gadget);
} catch (Exception $e) {
- $this->outputError($e);
- }
- }
-
- /**
- * If an error occured (Exception) this function echo's the Exception's message
- * and if the config['debug'] is true, shows the debug backtrace in a div
- *
- * @param Exception $e the exception to show
- */
- private function outputError($e) {
- header("HTTP/1.0 400 Bad Request", true, 400);
- echo "<html><body>";
- echo "<h1>Error</h1>";
- echo $e->getMessage();
- if (Config::get('debug')) {
- echo "<p><b>Debug backtrace</b></p><div style='overflow:auto; height:300px; border:1px solid #000000'><pre>";
- print_r(debug_backtrace());
- echo "</pre></div>>";
+ $this->showError($e);
}
- echo "</body></html>";
}
- /**
- * Takes the gadget to output, and depending on its content type calls either outputHtml-
- * or outputUrlGadget
- *
- * @param Gadget $gadget gadget to render
- * @param string $view the view to render (only valid with a html content type)
- */
- private function outputGadget($gadget, $context) {
- $view = HttpUtil::getView($gadget, $context);
- switch ($view->getType()) {
- case 'HTML':
- $this->outputHtmlGadget($gadget, $context, $view);
- break;
- case 'URL':
- $this->outputUrlGadget($gadget, $context, $view);
- break;
+ private function renderGadget(Gadget $gadget) {
+ $view = $gadget->getView($this->context->getView());
+ if ($view['type'] == 'URL') {
+ require_once "src/gadgets/render/GadgetUrlRenderer.php";
+ $gadgetRenderer = new GadgetUrlRenderer($this->context);
+ } elseif ($view['type'] == 'HTML' && empty($view['href'])) {
+ require_once "src/gadgets/render/GadgetHtmlRenderer.php";
+ $gadgetRenderer = new GadgetHtmlRenderer($this->context);
+ } elseif (empty($view['type']) || ! empty($view['href'])) {
+ require_once "src/gadgets/render/GadgetHrefRenderer.php";
+ $gadgetRenderer = new GadgetHrefRenderer($this->context);
+ } else {
+ throw new GadgetException("Invalid view type");
}
+ $gadgetRenderer->renderGadget($gadget, $view);
}
- /**
- * Outputs a html content type gadget.
- * It creates a html page, with the javascripts from the features inline into the page, plus
- * calls to 'gadgets.config.init' with the container configuration (config/container.js) and
- * 'gadgets.Prefs.setMessages_' with all the substitutions. For external javascripts it adds
- * a <script> tag.
- *
- * @param Gadget $gadget
- * @param GadgetContext $context
- */
- private function outputHtmlGadget($gadget, $context, $view) {
- $content = '';
- $externJs = '';
- $externFmt = "<script src=\"%s\"></script>";
- $forcedLibs = $context->getForcedJsLibs();
- // allow the &libs=.. param to override our forced js libs configuration value
- if (empty($forcedLibs)) {
- $forcedLibs = Config::get('focedJsLibs');
- }
+ private function setCachingHeaders() {
$this->setContentType("text/html; charset=UTF-8");
- if ($context->getIgnoreCache()) {
+ if ($this->context->getIgnoreCache()) {
// no cache was requested, set non-caching-headers
$this->setNoCache(true);
} elseif (isset($_GET['v'])) {
@@ -152,299 +97,19 @@
// no version was given, cache for 5 minutes
$this->setCacheTime(5 * 60);
}
- // Was a privacy policy header configured? if so set it
- if (Config::get('P3P') != '') {
- header("P3P: " . Config::get('P3P'));
- }
- if (! $view->getQuirks()) {
- $content .= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n";
- }
- $content .= "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><style type=\"text/css\">" . Config::get('gadget_css') . "</style></head><body>\n";
- // Forced libs first.
- if (! empty($forcedLibs)) {
- $libs = explode(':', $forcedLibs);
- $content .= sprintf($externFmt, Config::get('default_js_prefix') . $this->getJsUrl($libs, $gadget) . "&container=" . $context->getContainer()) . "\n";
- }
- $content .= "<script>\n";
-
- if (! empty($forcedLibs)) {
- // if some of the feature libraries are externalized (through a browser cachable <script src="/gadgets/js/opensocial-0.7:settitle.js">
- // type url), then we don't want to include dependencies twice, so find the complete features chain, so we can skip over those
- $forcedLibsArray = explode(':', $forcedLibs);
- $registry = $this->context->getRegistry();
- $missing = array();
- $registry->getIncludedFeatures($forcedLibsArray, $forcedLibsArray, $missing);
- }
- foreach ($gadget->getJsLibraries() as $library) {
- $type = $library->getType();
- if ($type == 'URL') {
- // TODO: This case needs to be handled more gracefully by the js
- // servlet. We should probably inline external JS as well.
- $externJs .= sprintf($externFmt, $library->getContent()) . "\n";
- // else check if there are no forcedLibs, or if it wasn't included in their dep chain
- } elseif (empty($forcedLibs) || ! in_array($library->getFeatureName(), $forcedLibsArray)) {
- $content .= $library->getContent();
- }
- // otherwise it was already included by config.forceJsLibs.
- }
- $content .= $this->appendJsConfig($context, $gadget, ! empty($forcedLibs)) . $this->appendMessages($gadget) . $this->appendPreloads($gadget, $context) . "</script>";
- if (strlen($externJs) > 0) {
- $content .= $externJs;
- }
- $gadgetExceptions = array();
- $rewriter = new ContentRewriter();
- if ($rewriter->rewriteGadgetView($gadget, $view)) {
- $content .= $gadget->getSubstitutions()->substitute($view->getRewrittenContent());
- } else {
- $content .= $gadget->getSubstitutions()->substitute($view->getContent());
- }
- if (empty($content)) {
- // Unknown view
- $gadgetExceptions[] = "View: '" . $context->getView() . "' invalid for gadget: " . $gadget->getId()->getKey();
- }
- if (count($gadgetExceptions)) {
- throw new GadgetException(print_r($gadgetExceptions, true));
- }
- $content .= "\n<script>gadgets.util.runOnLoadHandlers();</script></body>\n</html>";
- echo $content;
}
- /**
- * Output's a URL content type gadget, it adds libs=<list:of:js:libraries>.js and user preferences
- * to the href url, and redirects the browser to it
- *
- * @param Gadget $gadget
- */
- private function outputUrlGadget($gadget, $context, $view) {
- // Preserve existing query string parameters.
- $redirURI = $view->getHref();
- $queryStr = strpos($redirURI, '?') !== false ? substr($redirURI, strpos($redirURI, '?')) : '';
- $query = $queryStr;
- // TODO: userprefs on the fragment rather than query string
- $query .= $this->getPrefsQueryString($gadget->getUserPrefValues());
- $libs = array();
- $forcedLibs = Config::get('focedJsLibs');
- if ($forcedLibs == null) {
- $reqs = $gadget->getRequires();
- foreach ($reqs as $key => $val) {
- $libs[] = $key;
- }
- } else {
- $libs = explode(':', $forcedLibs);
- }
- $query .= $this->appendLibsToQuery($libs, $gadget);
- // code bugs out with me because of the invalid url syntax since we dont have a URI class to fix it for us
- // this works around that
- if (substr($query, 0, 1) == '&') {
- $query = '?' . substr($query, 1);
+ private function showError($e) {
+ header("HTTP/1.0 400 Bad Request", true, 400);
+ echo "<html><body>";
+ echo "<h1>Error</h1>";
+ echo $e->getMessage();
+ if (Config::get('debug')) {
+ echo "<p><b>Debug backtrace</b></p><div style='overflow:auto; height:300px; border:1px solid #000000'><pre>";
+ print_r(debug_backtrace());
+ echo "</pre></div>>";
}
- $redirURI .= $query;
- header('Location: ' . $redirURI);
+ echo "</body></html>";
die();
}
-
- /**
- * Returns the requested libs (from getjsUrl) with the libs_param_name prepended
- * ie: in libs=core:caja:etc.js format
- *
- * @param string $libs the libraries
- * @param Gadget $gadget
- * @return string the libs=... string to append to the redirection url
- */
- private function appendLibsToQuery($libs, $gadget) {
- $ret = "&";
- $ret .= Config::get('libs_param_name');
- $ret .= "=";
- $ret .= $this->getJsUrl($libs, $gadget);
- return $ret;
- }
-
- /**
- * Returns the user preferences in &up_<name>=<val> format
- *
- * @param array $libs array of features this gadget requires
- * @param Gadget $gadget
- * @return string the up_<name>=<val> string to use in the redirection url
- */
- private function getPrefsQueryString($prefVals) {
- $ret = '';
- foreach ($prefVals->getPrefs() as $key => $val) {
- $ret .= '&';
- $ret .= Config::get('userpref_param_prefix');
- $ret .= urlencode($key);
- $ret .= '=';
- $ret .= urlencode($val);
- }
- return $ret;
- }
-
- /**
- * generates the library string (core:caja:etc.js) including a checksum of all the
- * javascript content (?v=<md5 of js>) for cache busting
- *
- * @param string $libs
- * @param Gadget $gadget
- * @return string the list of libraries in core:caja:etc.js?v=checksum> format
- */
- private function getJsUrl($libs, $gadget) {
- $buf = '';
- if (! is_array($libs) || ! count($libs)) {
- $buf = 'core';
- } else {
- $firstDone = false;
- foreach ($libs as $lib) {
- if ($firstDone) {
- $buf .= ':';
- } else {
- $firstDone = true;
- }
- $buf .= $lib;
- }
- }
- $cache = Config::get('feature_cache');
- $cache = new $cache();
- if (($md5 = $cache->get(md5('getJsUrlMD5'))) === false) {
- $registry = $this->context->getRegistry();
- $features = $registry->getAllFeatures();
- // Build a version string from the md5() checksum of all included javascript
- // to ensure the client always has the right version
- $inlineJs = '';
- foreach ($features as $feature) {
- $library = $feature->getFeature();
- $libs = $library->getLibraries($this->context->getRenderingContext());
- foreach ($libs as $lib) {
- $inlineJs .= $lib->getContent();
- }
- }
- $md5 = md5($inlineJs);
- $cache->set(md5('getJsUrlMD5'), $md5);
- }
- $buf .= ".js?v=" . $md5;
- return $buf;
- }
-
- private function appendJsConfig($context, $gadget, $hasForcedLibs) {
- $container = $context->getContainer();
- $containerConfig = $context->getContainerConfig();
- //TODO some day we should parse the forcedLibs too, and include their config selectivly as well
- // for now we just include everything if forced libs is set.
- if ($hasForcedLibs) {
- $gadgetConfig = $containerConfig->getConfig($container, 'gadgets.features');
- } else {
- $gadgetConfig = array();
- $featureConfig = $containerConfig->getConfig($container, 'gadgets.features');
- foreach ($gadget->getJsLibraries() as $library) {
- $feature = $library->getFeatureName();
- if (! isset($gadgetConfig[$feature]) && ! empty($featureConfig[$feature])) {
- $gadgetConfig[$feature] = $featureConfig[$feature];
- }
- }
- }
-
- // Add gadgets.util support. This is calculated dynamically based on request inputs.
- // See java/org/apache/shindig/gadgets/render/RenderingContentRewriter.java for reference.
- $requires = array();
- foreach ($gadget->getRequires() as $feature) {
- $requires[$feature->name] = new EmptyClass();
- }
- $gadgetConfig['core.util'] = $requires;
-
- return "gadgets.config.init(" . json_encode($gadgetConfig) . ");\n";
- }
-
- private function appendMessages($gadget) {
- $msgs = '';
- if ($gadget->getMessageBundle()) {
- $bundle = $gadget->getMessageBundle();
- $msgs = json_encode($bundle->getMessages());
- }
- return "gadgets.Prefs.setMessages_($msgs);\n";
- }
-
- /**
- * Appends data from <Preload> elements to make them available to
- * gadgets.io.
- *
- * @param gadget
- */
- private function appendPreloads(Gadget $gadget, GadgetContext $context) {
- $resp = Array();
- $gadgetSigner = Config::get('security_token_signer');
- $gadgetSigner = new $gadgetSigner();
- $token = '';
- try {
- $token = $context->extractAndValidateToken($gadgetSigner);
- } catch (Exception $e) {
- $token = '';
- // no token given, safe to ignore
- }
- $unsignedRequests = $unsignedContexts = Array();
- $signedRequests = Array();
- foreach ($gadget->getPreloads() as $preload) {
- try {
- if (($preload->getAuth() == Auth::$NONE || $token != null) && (count($preload->getViews()) == 0 || in_array($context->getView(), $preload->getViews()))) {
- $request = new RemoteContentRequest($preload->getHref());
- $request->createRemoteContentRequestWithUri($preload->getHref());
- $request->getOptions()->ownerSigned = $preload->isSignOwner();
- $request->getOptions()->viewerSigned = $preload->isSignViewer();
- switch (strtoupper(trim($preload->getAuth()))) {
- case "NONE":
- // Unify all unsigned requests to one single multi request
- $unsignedRequests[] = $request;
- $unsignedContexts[] = $context;
- break;
- case "SIGNED":
- // Unify all signed requests to one single multi request
- $signingFetcherFactory = new SigningFetcherFactory(Config::get("private_key_file"));
- $fetcher = $signingFetcherFactory->getSigningFetcher(new BasicRemoteContentFetcher(), $token);
- $req = $fetcher->signRequest($preload->getHref(), $request->getMethod());
- $req->setNotSignedUri($preload->getHref());
- $signedRequests[] = $req;
- break;
- default:
- @ob_end_clean();
- header("HTTP/1.0 500 Internal Server Error", true);
- echo "<html><body><h1>" . "500 - Internal Server Error" . "</h1></body></html>";
- die();
- }
- }
- } catch (Exception $e) {
- throw new Exception($e);
- }
- }
- if (count($unsignedRequests)) {
- try {
- $brc = new BasicRemoteContent();
- $responses = $brc->multiFetch($unsignedRequests, $unsignedContexts);
- foreach ($responses as $response) {
- $resp[$response->getUrl()] = array(
- 'body' => $response->getResponseContent(),
- 'rc' => $response->getHttpCode());
- }
- } catch (Exception $e) {
- throw new Exception($e);
- }
- }
- if (count($signedRequests)) {
- try {
- $fetcher = $signingFetcherFactory->getSigningFetcher(new BasicRemoteContentFetcher(), $token);
- $responses = $fetcher->multiFetchRequest($signedRequests);
- foreach ($responses as $response) {
- $resp[$response->getNotSignedUrl()] = array(
- 'body' => $response->getResponseContent(),
- 'rc' => $response->getHttpCode());
- }
- } catch (Exception $e) {
- throw new Exception($e);
- }
- }
- $resp = count($resp) ? json_encode($resp) : "{}";
- return "gadgets.io.preloaded_ = " . $resp . ";\n";
- }
-}
-
-/*
- * An empty class for generate "{}" code in JavaScript.
- */
-class EmptyClass {
}
Modified: incubator/shindig/trunk/php/src/gadgets/servlet/JsServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/servlet/JsServlet.php?rev=744702&r1=744701&r2=744702&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/servlet/JsServlet.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/servlet/JsServlet.php Sun Feb 15 17:35:05 2009
@@ -19,12 +19,8 @@
*/
require 'src/common/HttpServlet.php';
+require 'src/gadgets/GadgetContext.php';
require 'src/gadgets/GadgetFeatureRegistry.php';
-require 'src/gadgets/JsFeatureLoader.php';
-require 'src/gadgets/JsLibrary.php';
-require 'src/gadgets/GadgetFeatureFactory.php';
-require 'src/gadgets/GadgetFeature.php';
-require 'src/gadgets/JsLibraryFeatureFactory.php';
/**
* This event handler deals with the /js/core:caja:etc.js request which content type=url gadgets can use
@@ -58,29 +54,14 @@
}
$found = array();
$missing = array();
+ $context = new GadgetContext('GADGET');
$registry = new GadgetFeatureRegistry(Config::get('features_path'));
- if ($registry->getIncludedFeatures($needed, $found, $missing)) {
- $containerParam = isset($_GET["c"]) ? $_GET["c"] : '';
- $context = $containerParam == '1' ? 'CONTAINER' : 'GADGET';
+ if ($registry->resolveFeatures($needed, $found, $missing)) {
+ $isGadgetContext = !isset($_GET["c"]) || $_GET['c'] == 0 ? true : false;
$jsData = '';
- $done = array();
- do {
- foreach ($found as $entry) {
- if (! in_array($entry, $done)) {
- $feat = $registry->getEntry($entry);
- $feature = $feat->getFeature();
- if ($feature instanceof JsLibraryFeatureFactory) {
- $jsLib = $feature;
- foreach ($jsLib->getLibraries($context) as $lib) {
- if ($lib->getType() != 'URL') {
- $jsData .= $lib->getContent() . "\n";
- }
- }
- }
- $done[] = $entry;
- }
- }
- } while (count($done) != count($found));
+ foreach ($found as $feature) {
+ $jsData .= $registry->getFeatureContent($feature, $context, $isGadgetContext);
+ }
if (! strlen($jsData)) {
header("HTTP/1.0 404 Not Found", true);
die();
@@ -95,6 +76,7 @@
}
private function setCachingHeaders() {
+ // Expires far into the future
header("Expires: Tue, 01 Jan 2030 00:00:01 GMT");
// IE seems to need this (10 years should be enough).
header("Cache-Control: public,max-age=315360000");
Added: incubator/shindig/trunk/php/src/gadgets/servlet/MakeRequestServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/servlet/MakeRequestServlet.php?rev=744702&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/servlet/MakeRequestServlet.php (added)
+++ incubator/shindig/trunk/php/src/gadgets/servlet/MakeRequestServlet.php Sun Feb 15 17:35:05 2009
@@ -0,0 +1,62 @@
+<?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.
+ */
+
+require 'src/common/HttpServlet.php';
+require 'src/gadgets/GadgetContext.php';
+require 'src/gadgets/ProxyBase.php';
+require 'src/gadgets/MakeRequestHandler.php';
+require 'src/common/RemoteContentRequest.php';
+require 'src/common/RemoteContent.php';
+require 'src/common/Cache.php';
+require 'src/common/RemoteContentFetcher.php';
+require 'src/gadgets/oauth/OAuth.php';
+require 'src/gadgets/oauth/OAuthStore.php';
+
+class MakeRequestServlet extends HttpServlet {
+
+ public function doGet() {
+ try {
+ $this->noHeaders = true;
+ $context = new GadgetContext('GADGET');
+ $url = urldecode(isset($_GET['url']) ? $_GET['url'] : (isset($_POST['url']) ? $_POST['url'] : false));
+ if (! $url || empty($url)) {
+ header("HTTP/1.0 400 Bad Request", true);
+ echo "<html><body><h1>400 - Missing url parameter</h1></body></html>";
+ }
+ $method = (isset($_GET['httpMethod']) ? $_GET['httpMethod'] : (isset($_POST['httpMethod']) ? $_POST['httpMethod'] : 'GET'));
+ $signingFetcherFactory = $gadgetSigner = false;
+ if (! empty($_GET['authz']) || ! empty($_POST['authz'])) {
+ $gadgetSigner = Config::get('security_token_signer');
+ $gadgetSigner = new $gadgetSigner();
+ $signingFetcherFactory = new SigningFetcherFactory(Config::get("private_key_file"));
+ }
+ $makeRequestHandler = new MakeRequestHandler($context, $signingFetcherFactory);
+ $makeRequestHandler->fetchJson($url, $gadgetSigner, $method);
+ } catch (Exception $e) {
+ // catch all exceptions and give a 500 server error
+ header("HTTP/1.0 500 Internal Server Error");
+ echo "<h1>Internal server error</h1><p>" . $e->getMessage() . "</p>";
+ }
+ }
+
+ public function doPost() {
+ $this->doGet();
+ }
+}
Modified: incubator/shindig/trunk/php/src/gadgets/servlet/MetadataServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/servlet/MetadataServlet.php?rev=744702&r1=744701&r2=744702&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/servlet/MetadataServlet.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/servlet/MetadataServlet.php Sun Feb 15 17:35:05 2009
@@ -18,38 +18,26 @@
* under the License.
*/
-require 'src/common/HttpServlet.php';
-require 'src/gadgets/MetadataHandler.php';
-require 'src/gadgets/GadgetContext.php';
-require 'src/gadgets/MetadataContext.php';
-require 'src/common/Locale.php';
-require 'src/gadgets/GadgetServer.php';
-require 'src/common/RemoteContentRequest.php';
-require 'src/common/RemoteContent.php';
-require 'src/common/Cache.php';
-require 'src/common/RemoteContentFetcher.php';
-require 'src/gadgets/GadgetSpecParser.php';
-require 'src/gadgets/Gadget.php';
-require 'src/gadgets/GadgetId.php';
-require 'src/gadgets/UserPrefs.php';
-require 'src/gadgets/Substitutions.php';
-require 'src/gadgets/ViewSpec.php';
-require 'src/gadgets/GadgetFeatureRegistry.php';
-require 'src/gadgets/GadgetFeatureFactory.php';
-require 'src/gadgets/GadgetFeature.php';
-require 'src/gadgets/JsLibraryFeatureFactory.php';
-require 'src/gadgets/JsLibrary.php';
-require 'src/common/UrlGenerator.php';
-require 'src/gadgets/HttpUtil.php';
-require 'src/gadgets/LocaleSpec.php';
-require 'src/gadgets/LocaleMessageBundle.php';
-require 'src/gadgets/UserPref.php';
-require 'src/gadgets/FeatureSpec.php';
-require 'src/gadgets/MessageBundleParser.php';
-require 'src/gadgets/MessageBundle.php';
-require 'src/gadgets/GadgetException.php';
-require 'src/gadgets/rewrite/ContentRewriter.php';
-require 'src/gadgets/rewrite/ContentRewriteFeature.php';
+require_once 'src/common/HttpServlet.php';
+require_once 'src/common/JsMin.php';
+require_once 'src/common/SecurityTokenDecoder.php';
+require_once 'src/common/SecurityToken.php';
+require_once 'src/common/BlobCrypter.php';
+require_once 'src/common/RemoteContentRequest.php';
+require_once 'src/common/RemoteContent.php';
+require_once 'src/common/Cache.php';
+require_once 'src/common/RemoteContentFetcher.php';
+require_once 'src/common/sample/BasicRemoteContent.php';
+require_once 'src/common/sample/BasicRemoteContentFetcher.php';
+require_once 'src/gadgets/GadgetSpecParser.php';
+require_once 'src/gadgets/GadgetBlacklist.php';
+require_once 'src/gadgets/sample/BasicGadgetBlacklist.php';
+require_once 'src/gadgets/GadgetContext.php';
+require_once 'src/gadgets/GadgetSpec.php';
+require_once 'src/gadgets/Gadget.php';
+require_once 'src/gadgets/GadgetFactory.php';
+require_once 'src/gadgets/MetadataContext.php';
+require_once 'src/gadgets/MetadataHandler.php';
class MetadataServlet extends HttpServlet {
Modified: incubator/shindig/trunk/php/src/gadgets/servlet/ProxyServlet.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/servlet/ProxyServlet.php?rev=744702&r1=744701&r2=744702&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/servlet/ProxyServlet.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/servlet/ProxyServlet.php Sun Feb 15 17:35:05 2009
@@ -20,51 +20,28 @@
require 'src/common/HttpServlet.php';
require 'src/gadgets/GadgetContext.php';
-require 'src/common/SecurityTokenDecoder.php';
+require 'src/gadgets/ProxyBase.php';
require 'src/gadgets/ProxyHandler.php';
-require 'src/gadgets/GadgetException.php';
require 'src/common/RemoteContentRequest.php';
require 'src/common/RemoteContent.php';
require 'src/common/Cache.php';
require 'src/common/RemoteContentFetcher.php';
-require 'src/gadgets/oauth/OAuth.php';
-require 'src/gadgets/oauth/OAuthStore.php';
-require 'src/gadgets/rewrite/ContentRewriter.php';
-require 'src/gadgets/rewrite/ContentRewriteFeature.php';
class ProxyServlet extends HttpServlet {
public function doGet() {
try {
+ // Make sure the HttpServlet doesn't overwrite our headers
$this->noHeaders = true;
$context = new GadgetContext('GADGET');
- // those should be doable in one statement, but php seems to still evauluate the second ? and : pair,
- // so throws an error about undefined index on post, even though it found it in get ... odd bug
- $url = isset($_GET['url']) ? $_GET['url'] : false;
- if (! $url) {
- $url = isset($_POST['url']) ? $_POST['url'] : false;
- }
- // $url = urldecode($url);
- $method = isset($_GET['httpMethod']) ? $_GET['httpMethod'] : false;
- if (! $method) {
- $method = isset($_POST['httpMethod']) ? $_POST['httpMethod'] : 'GET';
- }
+ $url = (isset($_GET['url']) ? $_GET['url'] : (isset($_POST['url']) ? $_POST['url'] : false));
+ $url = urldecode($url);
if (! $url) {
header("HTTP/1.0 400 Bad Request", true);
echo "<html><body><h1>400 - Missing url parameter</h1></body></html>";
}
- $signingFetcherFactory = $gadgetSigner = false;
- if (! empty($_GET['authz']) || ! empty($_POST['authz'])) {
- $gadgetSigner = Config::get('security_token_signer');
- $gadgetSigner = new $gadgetSigner();
- $signingFetcherFactory = new SigningFetcherFactory(Config::get("private_key_file"));
- }
- $proxyHandler = new ProxyHandler($context, $signingFetcherFactory);
- if (! empty($_GET['output']) && $_GET['output'] == 'js') {
- $proxyHandler->fetchJson($url, $gadgetSigner, $method);
- } else {
- $proxyHandler->fetch($url, $gadgetSigner, $method);
- }
+ $proxyHandler = new ProxyHandler($context);
+ $proxyHandler->fetch($url);
} catch (Exception $e) {
// catch all exceptions and give a 500 server error
header("HTTP/1.0 500 Internal Server Error");