Author: chabotc
Date: Fri Jun 13 10:05:57 2008
New Revision: 667596

URL: http://svn.apache.org/viewvc?rev=667596&view=rev
Log:
SHINDIG-359 Adds support for preloading resources, and authenticated preloading 
(0.8 feature)

Added:
    incubator/shindig/trunk/php/src/gadgets/Auth.php
    incubator/shindig/trunk/php/src/gadgets/Preload.php
Modified:
    incubator/shindig/trunk/php/src/common/RemoteContentRequest.php
    incubator/shindig/trunk/php/src/gadgets/Gadget.php
    incubator/shindig/trunk/php/src/gadgets/GadgetContext.php
    incubator/shindig/trunk/php/src/gadgets/GadgetServer.php
    incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php
    incubator/shindig/trunk/php/src/gadgets/ProxyHandler.php
    incubator/shindig/trunk/php/src/gadgets/Substitutions.php
    incubator/shindig/trunk/php/src/gadgets/http/GadgetRenderingServlet.php
    incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php
    incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php

Modified: incubator/shindig/trunk/php/src/common/RemoteContentRequest.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/common/RemoteContentRequest.php?rev=667596&r1=667595&r2=667596&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/common/RemoteContentRequest.php (original)
+++ incubator/shindig/trunk/php/src/common/RemoteContentRequest.php Fri Jun 13 
10:05:57 2008
@@ -1,4 +1,5 @@
 <?php
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
@@ -33,7 +34,6 @@
        private $options;
        public $handle = false;
        public static $DEFAULT_CONTENT_TYPE = 
"application/x-www-form-urlencoded; charset=utf-8";
-       public static $DEFAULT_OPTIONS = array();
 
        public function __construct($uri, $headers = false, $postBody = false)
        {
@@ -55,16 +55,14 @@
                        $tmpHeaders = '';
                        foreach ($headers as $key => $value) {
                                // Proxies should be bypassed with the Pragma: 
no-cache check.
-                               //TODO double check array is good for options
-                               if ($key == "Pragma" && 
@$options['ignoreCache']) {
+                               if ($key == "Pragma" && $options->ignoreCache) {
                                        $value = "no-cache";
                                        $setPragmaHeader = true;
                                }
                                $tmpHeaders .= $key . ":" . $value . "\n";
                        }
                        // Bypass caching in proxies as well.
-                       //TODO double check array is good for options
-                       if (! $setPragmaHeader && @$options['ignoreCache']) {
+                       if (! $setPragmaHeader && $options->ignoreCache) {
                                $tmpHeaders .= "Pragma:no-cache\n";
                        }
                        $this->headers = $tmpHeaders;
@@ -106,7 +104,7 @@
         */
        public function createRemoteContentRequestWithUri($uri)
        {
-               $this->createRemoteContentRequest("GET", $uri, null, null, 
RemoteContentRequest::$DEFAULT_OPTIONS);
+               $this->createRemoteContentRequest("GET", $uri, null, null, 
RemoteContentRequest::getDefaultOptions());
        }
 
        /**
@@ -127,7 +125,7 @@
         */
        public function RemoteContentRequestWithUriHeaders($uri, $headers)
        {
-               $this->createRemoteContentRequest("GET", $uri, $headers, null, 
RemoteContentRequest::$DEFAULT_OPTIONS);
+               $this->createRemoteContentRequest("GET", $uri, $headers, null, 
RemoteContentRequest::getDefaultOptions());
        }
 
        /**
@@ -148,7 +146,7 @@
         */
        public function RemoteContentRequestWithUriPostBody($uri, $postBody)
        {
-               $this->createRemoteContentRequest("POST", $uri, null, 
$postBody, RemoteContentRequest::$DEFAULT_OPTIONS);
+               $this->createRemoteContentRequest("POST", $uri, null, 
$postBody, RemoteContentRequest::getDefaultOptions());
        }
 
        /**
@@ -170,7 +168,7 @@
         */
        public function createRemoteContentRequestWithUriHeadersPostBody($uri, 
$headers, $postBody)
        {
-               $this->createRemoteContentRequest("POST", $uri, $headers, 
$postBody, RemoteContentRequest::$DEFAULT_OPTIONS);
+               $this->createRemoteContentRequest("POST", $uri, $headers, 
$postBody, RemoteContentRequest::getDefaultOptions());
        }
 
        /**
@@ -205,6 +203,11 @@
                return md5($this->uri . $this->postBody);
        }
 
+       public static function getDefaultOptions()
+       {
+               return new Options();
+       }
+
        public function getContentType()
        {
                return $this->contentType;
@@ -262,6 +265,9 @@
 
        public function getOptions()
        {
+               if (empty($this->options)) {
+                       return new Options();
+               }
                return $this->options;
        }
 
@@ -328,4 +334,21 @@
  */
 class Options {
        public $ignoreCache = false;
+       public $ownerSigned = true;
+       public $viewerSigned = true;
+
+       public function __construct()
+       {
+       }
+
+       /**
+        * Copy constructor
+        */
+       public function copyOptions(Options $copyFrom)
+       {
+               $this->ignoreCache = $copyFrom->ignoreCache;
+               $this->ownerSigned = $copyFrom->ownerSigned;
+               $this->viewerSigned = $copyFrom->viewerSigned;
+       }
+
 }

Added: incubator/shindig/trunk/php/src/gadgets/Auth.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/Auth.php?rev=667596&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/Auth.php (added)
+++ incubator/shindig/trunk/php/src/gadgets/Auth.php Fri Jun 13 10:05:57 2008
@@ -0,0 +1,51 @@
+<?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 Auth {
+       
+       public static $NONE = "NONE";
+       public static $SIGNED = "SIGNED";
+       public static $AUTHENTICATED = "AUTHENTICATED";
+
+       /**
+        * @param value
+        * @return The parsed value (defaults to NONE)
+        */
+       public static function parse($value)
+       {
+               if (! empty($value)) {
+                       $value = trim($value);
+                       if (strlen($value) == 0)
+                               return Auth::$NONE;
+                       if (strtoupper($value == Auth::$SIGNED)) {
+                               return Auth::$SIGNED;
+                       } else 
+                               if (strtoupper($value == Auth::$AUTHENTICATED)) 
{
+                                       return Auth::$AUTHENTICATED;
+                               } else {
+                                       return Auth::$NONE;
+                               }
+               } else {
+                       return Auth::$NONE;
+               }
+       }
+
+}
\ No newline at end of file

Modified: incubator/shindig/trunk/php/src/gadgets/Gadget.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/Gadget.php?rev=667596&r1=667595&r2=667596&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/Gadget.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/Gadget.php Fri Jun 13 10:05:57 2008
@@ -1,4 +1,5 @@
 <?php
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
@@ -146,11 +147,7 @@
 
        public function getPreloads()
        {
-               $ret = array();
-               foreach ($this->preloads as $preload) {
-                       $ret[] = $this->substitutions->substitute($preload);
-               }
-               return $ret;
+               return $this->preloads;
        }
 
        public function getRequires()

Modified: incubator/shindig/trunk/php/src/gadgets/GadgetContext.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/GadgetContext.php?rev=667596&r1=667595&r2=667596&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/GadgetContext.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/GadgetContext.php Fri Jun 13 
10:05:57 2008
@@ -15,7 +15,7 @@
  * "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.
- * 
+ *
  */
 
 define('DEFAULT_VIEW', 'profile');
@@ -154,7 +154,7 @@
        private function instanceRegistry()
        {
                // Profiling showed 40% of the processing time was spend in the 
feature registry
-               // So by caching this and making it a one time initialization, 
we almost double the performance  
+               // So by caching this and making it a one time initialization, 
we almost double the performance
                if (! ($registry = 
$this->getCache()->get(md5(Config::get('features_path'))))) {
                        $registry = new 
GadgetFeatureRegistry(Config::get('features_path'));
                        
$this->getCache()->set(md5(Config::get('features_path')), $registry);
@@ -164,7 +164,7 @@
 
        private function instanceLocale()
        {
-               // Get language and country params, try the GET params first, 
if their not set try the POST, else use 'all' as default 
+               // Get language and country params, try the GET params first, 
if their not set try the POST, else use 'all' as default
                $language = ! empty($_GET['lang']) ? $_GET['lang'] : (! 
empty($_POST['lang']) ? $_POST['lang'] : 'all');
                $country = ! empty($_GET['country']) ? $_GET['country'] : (! 
empty($_POST['country']) ? $_POST['country'] : 'all');
                return new Locale($language, $country);
@@ -363,4 +363,24 @@
        {
                return $this->registry;
        }
+
+       /**
+        * Extracts the 'st' token from the GET or POST params and calls the
+        * signer to validate the token
+        *
+        * @param GadgetSigner $signer the signer to use (configured in 
config.php)
+        * @return string the token to use in the signed url
+        */
+       public function extractAndValidateToken($signer)
+       {
+               if ($signer == null) {
+                       return null;
+               }
+               $token = isset($_GET["st"]) ? $_GET["st"] : '';
+               if (! isset($token) || $token == '') {
+                       $token = isset($_POST['st']) ? $_POST['st'] : '';
+               }
+               return $signer->createToken($token);
+       }
+
 }

Modified: incubator/shindig/trunk/php/src/gadgets/GadgetServer.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/GadgetServer.php?rev=667596&r1=667595&r2=667596&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/GadgetServer.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/GadgetServer.php Fri Jun 13 
10:05:57 2008
@@ -1,4 +1,5 @@
 <?php
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
@@ -96,7 +97,7 @@
                return $localeSpec;
        }
 
-       private function featuresLoad($gadget, $context)
+       private function featuresLoad(Gadget $gadget, $context)
        {
                //NOTE i've been a bit liberal here with folding code into this 
function, while it did get a bit long, the many include()'s are slowing us down
                // Should really clean this up a bit in the future though
@@ -129,6 +130,8 @@
                $substitutor->addSubstitution('BIDI', "DIR", $rtl ? "rtl" : 
"ltr");
                $substitutor->addSubstitution('BIDI', "REVERSE_DIR", $rtl ? 
"ltr" : "rtl");
                
+               $this->substitutePreloads($gadget, $substitutor);
+               
                // userPref's
                $upValues = $gadget->getUserPrefValues();
                foreach ($gadget->getUserPrefs() as $pref) {
@@ -184,6 +187,15 @@
                        $feature->process($gadget, $context, $params);
                }
        }
+
+       private function substitutePreloads(Gadget $gadget, $substituter)
+       {
+               $preloads = array();
+               foreach ($gadget->preloads as $preload) {
+                       $preloads[] = $preload->substitute($substituter);
+               }
+               $gadget->preloads = $preloads;
+       }
 }
 
 

Modified: incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php?rev=667596&r1=667595&r2=667596&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/GadgetSpecParser.php Fri Jun 13 
10:05:57 2008
@@ -1,4 +1,5 @@
 <?php
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
@@ -44,6 +45,9 @@
                foreach ($doc->Content as $content) {
                        $this->processContent($gadget, $content);
                }
+               foreach ($doc->ModulePrefs->Preload as $feature) {
+                       $gadget->preloads[] = new Preload($feature);
+               }
                foreach ($doc->ModulePrefs->Require as $feature) {
                        $this->processFeature($gadget, $feature, true);
                }
@@ -206,4 +210,5 @@
                }
                $gadget->requires[$featureSpec->name] = $featureSpec;
        }
+
 }

Added: incubator/shindig/trunk/php/src/gadgets/Preload.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/Preload.php?rev=667596&view=auto
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/Preload.php (added)
+++ incubator/shindig/trunk/php/src/gadgets/Preload.php Fri Jun 13 10:05:57 2008
@@ -0,0 +1,100 @@
+<?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 Preload {
+       
+       public static $AUTHZ_ATTR = "authz";
+       
+       private $href;
+       private $auth;
+       private $signViewer;
+       private $signOwner;
+       private $views = array();
+
+       public function getHref()
+       {
+               return $this->href;
+       }
+
+       public function getAuth()
+       {
+               return $this->auth;
+       }
+
+       public function isSignViewer()
+       {
+               return $this->signViewer;
+       }
+
+       public function isSignOwner()
+       {
+               return $this->signOwner;
+       }
+
+       public function getViews()
+       {
+               return $this->views;
+       }
+
+       public function substitute($substituter)
+       {
+               return $this->fillPreload($this, $substituter);
+       }
+
+       /**
+        * Creates a new Preload from an xml node.
+        *
+        * @param preload The Preload to create
+        */
+       public function __construct(SimpleXMLElement $preload)
+       {
+               $attributes = $preload->attributes();
+               $this->signOwner = isset($attributes['sign_owner']) ? 
trim($attributes['sign_owner']) : true;
+               $this->signViewer = isset($attributes['sign_viewer']) ? 
trim($attributes['sign_viewer']) : true;
+               $this->href = isset($attributes['href']) ? 
trim($attributes['href']) : '';
+               if (empty($this->href)) {
+                       throw new SpecParserException("Preload/@href is missing 
or invalid.");
+               }
+               // Record all the associated views
+               $viewNames = isset($attributes['views']) ? 
trim($attributes['views']) : '';
+               $views = array();
+               $arrViewNames = explode(",", $viewNames);
+               foreach ($arrViewNames as $view) {
+                       $view = trim($view);
+                       if (strlen($view) > 0) {
+                               $views[] = $view;
+                       }
+               }
+               $this->views = $views;
+               $this->auth = Auth::parse($attributes[Preload::$AUTHZ_ATTR]);
+       }
+
+       private function fillPreload(Preload $preload, $substituter)
+       {
+               $this->signOwner = $preload->signOwner;
+               $this->signViewer = $preload->signViewer;
+               $this->views = $preload->views;
+               $this->auth = $preload->auth;
+               $this->href = $substituter->substituteUri(null, $preload->href);
+               return $this;
+       }
+
+}
\ No newline at end of file

Modified: incubator/shindig/trunk/php/src/gadgets/ProxyHandler.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/ProxyHandler.php?rev=667596&r1=667595&r2=667596&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/ProxyHandler.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/ProxyHandler.php Fri Jun 13 
10:05:57 2008
@@ -29,17 +29,17 @@
  *
  */
 class ProxyHandler {
-       private $context;
-       private $signingFetcher;
+       private $context;
+       private $signingFetcher;
        private $oauthFetcher;
-       
+
        public function __construct($context, $signingFetcher = null, 
$oauthFetcher = null)
        {
-               $this->context = $context;
+               $this->context = $context;
                $this->signingFetcher = $signingFetcher;
                $this->oauthFetcher = $oauthFetcher;
        }
-       
+
        /**
         * Fetches content and returns it in JSON format
         *
@@ -50,7 +50,7 @@
        public function fetchJson($url, $signer, $method)
        {
                try {
-                       $token = $this->extractAndValidateToken($signer);
+                       $token = 
$this->context->extractAndValidateToken($signer);
                } catch (Exception $e) {
                        $token = '';
                        // no token given, safe to ignore
@@ -59,16 +59,16 @@
                // 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)) {
+               if (! isset($result)) {
                        //OAuthFetcher only
                        $metadata = $this->oauthFetcher->getResponseMetadata();
                        $json = array($url => $metadata);
-                       $json = json_encode($json);
+                       $json = json_encode($json);
                        $output = UNPARSEABLE_CRUFT . $json;
                        $this->setCachingHeaders();
                        header("Content-Type: application/json; charset=utf-8", 
true);
                        echo $output;
-                       die();  
+                       die();
                }
                $status = (int)$result->getHttpCode();
                //header("HTTP/1.1 $status", true);
@@ -86,66 +86,55 @@
                                        try {
                                                $feed = 
Zend_Feed::importString($content);
                                                if ($feed instanceof 
Zend_Feed_Rss) {
-                                                       $channel = array(
-                                                           'title'             
=> $feed->title(),
-                                                           'link'              
=> $feed->link(),
-                                                           'description'       
=> $feed->description(),
-                                                               'pubDate'       
        => $feed->pubDate(),
-                                                               'language'      
        => $feed->language(),
-                                                               'category'      
        => $feed->category(),
-                                                           'items'             
=> array()
-                                                       );
+                                                       $channel = 
array('title' => $feed->title(), 
+                                                                       'link' 
=> $feed->link(), 
+                                                                       
'description' => $feed->description(), 
+                                                                       
'pubDate' => $feed->pubDate(), 
+                                                                       
'language' => $feed->language(), 
+                                                                       
'category' => $feed->category(), 'items' => array());
                                                        // Loop over each 
channel item and store relevant data
                                                        $counter = 0;
                                                        foreach ($feed as 
$item) {
                                                                if ($counter >= 
$numEntries) {
                                                                        break;
                                                                }
-                                                               $counter++;
-                                                           $channel['items'][] 
= array(
-                                                               'title'         
        => $item->title(),
-                                                               'link'          
        => $item->link(),
-                                                               'author'        
        => $item->author(),
-                                                               'description'   
=> $getSummaries ? $item->description() : '',
-                                                               'category'      
        => $item->category(),
-                                                               'comments'      
        => $item->comments(),
-                                                               'pubDate'       
        => $item->pubDate()
-                                                           );
+                                                               $counter ++;
+                                                               
$channel['items'][] = array('title' => $item->title(), 
+                                                                               
'link' => $item->link(), 
+                                                                               
'author' => $item->author(), 
+                                                                               
'description' => $getSummaries ? $item->description() : '', 
+                                                                               
'category' => $item->category(), 
+                                                                               
'comments' => $item->comments(), 
+                                                                               
'pubDate' => $item->pubDate());
                                                        }
                                                } elseif ($feed instanceof 
Zend_Feed_Atom) {
-                                                       $channel = array(
-                                                               'title'         
        => $feed->title(),
-                                                               'link'          
=> $feed->link(),
-                                                               'id'            
=> $feed->id(),
-                                                           'subtitle'          
=> $feed->subtitle(),
-                                                               'items'         
=> array()
-                                                       );
+                                                       $channel = 
array('title' => $feed->title(), 
+                                                                       'link' 
=> $feed->link(), 'id' => $feed->id(), 
+                                                                       
'subtitle' => $feed->subtitle(), 'items' => array());
                                                        $counter = 0;
                                                        foreach ($feed as 
$entry) {
                                                                if ($counter >= 
$numEntries) {
                                                                        break;
                                                                }
-                                                               
$channel['items'][] = array(
-                                                                       'id'    
        => $entry->id(),
-                                                                       'title' 
        => $entry->title(),
-                                                                       'link'  
        => $entry->link(),
-                                                                       
'summary'       => $entry->summary(),
-                                                                       
'content'       => $entry->content(),
-                                                                       
'author'        => $entry->author(),
-                                                                       
'published' => $entry->published(),
-                                                                       
'updated'       => $entry->updated()
-                                                               );
+                                                               
$channel['items'][] = array('id' => $entry->id(), 
+                                                                               
'title' => $entry->title(), 
+                                                                               
'link' => $entry->link(), 
+                                                                               
'summary' => $entry->summary(), 
+                                                                               
'content' => $entry->content(), 
+                                                                               
'author' => $entry->author(), 
+                                                                               
'published' => $entry->published(), 
+                                                                               
'updated' => $entry->updated());
                                                        }
                                                } else {
                                                        throw new 
Exception('Invalid feed type');
                                                }
                                                $resp = json_encode($channel);
                                        } catch (Zend_Feed_Exception $e) {
-                                               $resp = 'Error parsing feed: 
'.$e->getMessage();
+                                               $resp = 'Error parsing feed: ' 
. $e->getMessage();
                                        }
                                } else {
-                                   // feed import failed
-                                   $resp = "Error fetching feed, response 
code: ".$result->getHttpCode();
+                                       // feed import failed
+                                       $resp = "Error fetching feed, response 
code: " . $result->getHttpCode();
                                }
                        } else {
                                $resp = $result->getResponseContent();
@@ -175,7 +164,7 @@
        public function fetch($url, $signer, $method)
        {
                try {
-                       $token = $this->extractAndValidateToken($signer);
+                       $token = 
$this->context->extractAndValidateToken($signer);
                } catch (Exception $e) {
                        $token = '';
                        // no token given, safe to ignore
@@ -187,7 +176,7 @@
                $status = (int)$result->getHttpCode();
                if ($status == 200) {
                        $headers = explode("\n", $result->getResponseHeaders());
-                       foreach ( $headers as $header ) {
+                       foreach ($headers as $header) {
                                if (strpos($header, ':')) {
                                        $key = trim(substr($header, 0, 
strpos($header, ':')));
                                        $val = trim(substr($header, 
strpos($header, ':') + 1));
@@ -209,7 +198,7 @@
                // make sure the HttpServlet destructor doesn't override ours
                die();
        }
-       
+
        /**
         * Both fetch and fetchJson call this function to retrieve the actual 
content
         *
@@ -220,13 +209,14 @@
        private function fetchContent($url, $method)
        {
                //TODO get actual character encoding from the request
+               
 
                // 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 ) {
+               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";
@@ -241,7 +231,7 @@
                        if ($data) {
                                $data = urldecode($data);
                                $entries = explode('&', $data);
-                               foreach ( $entries as $entry ) {
+                               foreach ($entries as $entry) {
                                        $parts = explode('=', $entry);
                                        // Process only if its a valid 
value=something pair
                                        if (count($parts) == 2) {
@@ -267,7 +257,7 @@
        private function fetchContentDivert($url, $method, $signer)
        {
                $authz = isset($_GET['authz']) ? $_GET['authz'] : 
(isset($_POST['authz']) ? $_POST['authz'] : '');
-               $token = $this->extractAndValidateToken($signer);
+               $token = $this->context->extractAndValidateToken($signer);
                switch (strtoupper($authz)) {
                        case 'SIGNED':
                                $fetcher = 
$this->signingFetcher->getSigningFetcher(new BasicRemoteContentFetcher(), 
$token);
@@ -285,12 +275,12 @@
                                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. 
@@ -302,7 +292,7 @@
                header("Cache-Control: private; max-age=0", true);
                header("Expires: " . gmdate("D, d M Y H:i:s", time() - 3000) . 
" GMT", true);
        }
-       
+
        /**
         * Empty function, should make something practical here some day.
         * it's function should be to validate the given url if its in
@@ -317,26 +307,7 @@
                // why not use Zend::Uri:
                return $url;
        }
-       
-       /**
-        * Extracts the 'st' token from the GET or POST params and calls the
-        * signer to validate the token
-        *
-        * @param GadgetSigner $signer the signer to use (configured in 
config.php)
-        * @return string the token to use in the signed url
-        */
-       private function extractAndValidateToken($signer)
-       {
-               if ($signer == null) {
-                       return null;
-               }
-               $token = isset($_GET["st"]) ? $_GET["st"] : '';
-               if (!isset($token) || $token == '') {
-                       $token = isset($_POST['st']) ? $_POST['st'] : '';
-               }
-               return $signer->createToken($token);
-       }
-               
+
        private function request_headers()
        {
                // Try to use apache's request headers if available
@@ -347,7 +318,7 @@
                }
                // if that failed, try to create them from the _SERVER 
superglobal
                $headers = array();
-               foreach ( array_keys($_SERVER) as $skey ) {
+               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];

Modified: incubator/shindig/trunk/php/src/gadgets/Substitutions.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/Substitutions.php?rev=667596&r1=667595&r2=667596&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/Substitutions.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/Substitutions.php Fri Jun 13 
10:05:57 2008
@@ -15,13 +15,13 @@
  * "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 Substitutions {
        private $types = array('MESSAGE' => 'MSG', 'BIDI' => 'BIDI', 
'USER_PREF' => 'UP', 
                        'MODULE' => 'MODULE');
-       
+
        private $substitutions = array();
 
        public function __construct()
@@ -53,6 +53,26 @@
 
        public function substituteType($type, $input)
        {
+               if (empty($this->substitutions[$type])) {
+                       return $input;
+               }
                return str_replace(array_keys($this->substitutions[$type]), 
array_values($this->substitutions[$type]), $input);
        }
+
+       /**
+        * Substitutes a uri
+        * @param type The type to substitute, or null for all types.
+        * @param uri
+        * @return The substituted uri, or a dummy value if the result is 
invalid.
+        */
+       public function substituteUri($type, $uri) {
+               if (empty($uri)) {
+                       return null;
+               }
+               try {
+                       return $this->substituteType($type, $uri);
+               } catch (Exception $e) {
+                       return "";
+               }
+       }
 }
\ No newline at end of file

Modified: 
incubator/shindig/trunk/php/src/gadgets/http/GadgetRenderingServlet.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/http/GadgetRenderingServlet.php?rev=667596&r1=667595&r2=667596&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/http/GadgetRenderingServlet.php 
(original)
+++ incubator/shindig/trunk/php/src/gadgets/http/GadgetRenderingServlet.php Fri 
Jun 13 10:05:57 2008
@@ -157,15 +157,16 @@
                                // 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 if ($type == 'INLINE') {
-                               echo $library->getContent();
-                       } else {
-                               // FILE or RESOURCE
-                               if ($forcedLibs == null) {
-                                       echo $library->getContent() . "\n";
+                       } else 
+                               if ($type == 'INLINE') {
+                                       echo $library->getContent();
+                               } else {
+                                       // FILE or RESOURCE
+                                       if ($forcedLibs == null) {
+                                               echo $library->getContent() . 
"\n";
+                                       }
+                                       // otherwise it was already included by 
config.forceJsLibs.
                                }
-                               // otherwise it was already included by 
config.forceJsLibs.
-                       }
                }
                echo "\n-->\n</script>\n";
                // Forced libs first.
@@ -176,8 +177,7 @@
                if (strlen($externJs) > 0) {
                        echo $externJs;
                }
-               echo "<script><!--\n" . $this->appendJsConfig($context, 
$gadget) . $this->appendMessages($gadget) . "-->\n</script>\n";
-               
+               echo "<script><!--\n" . $this->appendJsConfig($context, 
$gadget) . $this->appendMessages($gadget) . $this->appendPreloads($gadget, 
$context) . "-->\n</script>\n";
                $gadgetExceptions = array();
                $content = 
$gadget->getSubstitutions()->substitute($view->getContent());
                if (empty($content)) {
@@ -323,4 +323,60 @@
                }
                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 = '';
+               $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
+               }
+               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":
+                                                       $brc = new 
BasicRemoteContent();
+                                                       $response = 
$brc->fetch($request, $context);
+                                                       break;
+                                               case "SIGNED":
+                                                       $signingFetcherFactory 
= new SigningFetcherFactory(Config::get("private_key_file"));
+                                                       $fetcher = 
$signingFetcherFactory->getSigningFetcher(new BasicRemoteContentFetcher(), 
$token);
+                                                       $response = 
$fetcher->fetch($preload->getHref(), $request->getMethod());
+                                                       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();
+                                       }
+                                       $json = array(
+                                                       $preload->getHref() => 
array(
+                                                                       'body' 
=> $response->getResponseContent(), 
+                                                                       'rc' => 
$response->getHttpCode()));
+                                       $resp .= json_encode($json);
+                               }
+                       } catch (Exception $e) {
+                               throw new Exception($e);
+                       }
+               }
+               $resp = $resp == '' ? "{}" : $resp;
+               return "gadgets.io.preloaded_ = " . $resp . ";\n";
+       }
+
+}
\ No newline at end of file

Modified: incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php?rev=667596&r1=667595&r2=667596&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuth.php Fri Jun 13 10:05:57 
2008
@@ -1,4 +1,5 @@
 <?php
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -264,9 +265,10 @@
                        $header_parameters = 
OAuthRequest::split_header($request_headers['Authorization']);
                        if ($http_method == "GET") {
                                $req_parameters = $_GET;
-                       } else if ($http_method = "POST") {
-                               $req_parameters = $_POST;
-                       }
+                       } else 
+                               if ($http_method = "POST") {
+                                       $req_parameters = $_POST;
+                               }
                        $parameters = array_merge($header_parameters, 
$req_parameters);
                        $req = new OAuthRequest($http_method, $http_url, 
$parameters);
                } elseif ($http_method == "GET") {
@@ -285,8 +287,7 @@
                $parameters = is_array($parameters) ? $parameters : array();
                $defaults = array("oauth_nonce" => 
OAuthRequest::generate_nonce(), 
                                "oauth_timestamp" => 
OAuthRequest::generate_timestamp(), 
-                               "oauth_consumer_key" => $consumer->key, // 
quick hack to make this demo'able
-'synd' => 'partuza', 
+                               "oauth_consumer_key" => $consumer->key, 'synd' 
=> 'partuza', 
                                'container' => 'partuza');
                $parameters = array_merge($defaults, $parameters);
                if (isset($token)) {
@@ -867,7 +868,9 @@
                $explodedForm = explode("&", $form);
                foreach ($explodedForm as $params) {
                        $value = explode("=", $params);
-                       $parameters[OAuthUtil::urldecodeRFC3986($value[0])] = 
OAuthUtil::urldecodeRFC3986($value[1]);
+                       if (! empty($value[0]) && ! empty($value[1])) {
+                               
$parameters[OAuthUtil::urldecodeRFC3986($value[0])] = 
OAuthUtil::urldecodeRFC3986($value[1]);
+                       }
                }
                return $parameters;
        }

Modified: incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php?rev=667596&r1=667595&r2=667596&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/oauth/OAuthFetcher.php Fri Jun 13 
10:05:57 2008
@@ -1,4 +1,5 @@
 <?php
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements. See the NOTICE file distributed with this
@@ -15,7 +16,7 @@
  * License for the specific language governing permissions and limitations 
under
  * the License.
  */
-
+
 /**
  * Implements the OAuth dance (http://oauth.net/core/1.0/) for gadgets.
  *
@@ -26,7 +27,7 @@
  * requires OAuth signing.
  */
 class OAuthFetcher extends RemoteContentFetcher {
-
+       
        // We store some blobs of data on the client for later reuse; the blobs
        // contain key/value pairs, and these are the key names.
        private static $REQ_TOKEN_KEY = "r";
@@ -34,66 +35,66 @@
        private static $ACCESS_TOKEN_KEY = "a";
        private static $ACCESS_TOKEN_SECRET_KEY = "as";
        private static $OWNER_KEY = "o";
-
+       
        // names for the JSON values we return to the client
        public static $CLIENT_STATE = "oauthState";
        public static $APPROVAL_URL = "approvalUrl";
        // names of additional OAuth parameters we include in outgoing requests
        public static $XOAUTH_APP_URL = "xoauth_app_url";
-
+       
        /**
         * Maximum age for our client state; if this is exceeded we start over. 
One
         * hour is a fairly arbitrary time limit here.
         */
        private static $CLIENT_STATE_MAX_AGE_SECS = 3600;
-
+       
        /**
         * The gadget security token, with info about owner/viewer/gadget.
         */
        protected $authToken;
-
+       
        /**
         * The gadget's nickname for the service provider.
         */
        protected $serviceName;
-
+       
        /**
         * The gadget's nickname for the token.
         */
        protected $tokenName;
-
+       
        /**
         * Reference to our persistent store for OAuth metadata.
         */
        protected $tokenStore;
-
+       
        /**
         * The accessor we use for signing messages. This also holds metadata 
about
         * the service provider, such as their URLs and the keys we use to 
access
         * those URLs.
         */
        private $accessorInfo;
-
+       
        /**
         * We use this to encrypt and sign the state we cache on the client.
         */
        private $oauthCrypter;
-
+       
        /**
         * State the client sent with their request.
         */
        private $origClientState = array();
-
+       
        /**
         * The request the client really wants to make.
         */
        private $realRequest;
-
+       
        /**
         * State to cache on the client.
         */
        private $newClientState;
-
+       
        /**
         * Authorization URL for the client
         */
@@ -120,8 +121,8 @@
                if ($origClientState != null && strlen($origClientState) > 0) {
                        try {
                                $this->origClientState = 
$this->oauthCrypter->unwrap($origClientState, 
OAuthFetcher::$CLIENT_STATE_MAX_AGE_SECS);
-                       } catch (BlobCrypterException $e) {     // Probably too 
old, pretend we never saw it at all.
-                       }
+                       } catch (BlobCrypterException $e) {// Probably too old, 
pretend we never saw it at all.
+}
                }
                if ($this->origClientState == null) {
                        $this->origClientState = array();
@@ -149,10 +150,11 @@
                if 
(isset($this->origClientState[OAuthFetcher::$REQ_TOKEN_KEY])) {
                        $accessor->requestToken = 
$this->origClientState[OAuthFetcher::$REQ_TOKEN_KEY];
                        $accessor->tokenSecret = 
$this->origClientState[OAuthFetcher::$REQ_TOKEN_SECRET_KEY];
-               } else if 
(isset($this->origClientState[OAuthFetcher::$ACCESS_TOKEN_KEY])) {
-                       $accessor->accessToken = 
$this->origClientState[OAuthFetcher::$ACCESS_TOKEN_KEY];
-                       $accessor->tokenSecret = 
$this->origClientState[OAuthFetcher::$ACCESS_TOKEN_SECRET_KEY];
-               }
+               } else 
+                       if 
(isset($this->origClientState[OAuthFetcher::$ACCESS_TOKEN_KEY])) {
+                               $accessor->accessToken = 
$this->origClientState[OAuthFetcher::$ACCESS_TOKEN_KEY];
+                               $accessor->tokenSecret = 
$this->origClientState[OAuthFetcher::$ACCESS_TOKEN_SECRET_KEY];
+                       }
        }
 
        private function buildTokenKey()
@@ -248,7 +250,7 @@
                if (! isset($params)) {
                        throw new Exception("params was null in " + 
"newRequestMessage " + "Use newRequesMessage if you don't have a params to 
pass");
                }
-
+               
                switch ($this->accessorInfo->getSignatureType()) {
                        case OAuth::$RSA_SHA1:
                                $params[OAuth::$OAUTH_SIGNATURE_METHOD] = 
OAuth::$RSA_SHA1;
@@ -286,11 +288,13 @@
        {
                if (isset($method) && isset($url) && isset($params)) {
                        return $this->newRequestMessageMethod($method, $url, 
$params);
-               } else if (isset($url) && isset($params)) {
-                       return $this->newRequestMessageParams($url, $params);
-               } else if (isset($url)) {
-                       return $this->newRequestMessageUrlOnly($url);
-               }
+               } else 
+                       if (isset($url) && isset($params)) {
+                               return $this->newRequestMessageParams($url, 
$params);
+                       } else 
+                               if (isset($url)) {
+                                       return 
$this->newRequestMessageUrlOnly($url);
+                               }
        }
 
        private function getAuthorizationHeader($oauthParams)
@@ -322,7 +326,7 @@
                                $authHeader = 
$this->getAuthorizationHeader($oauthParams);
                                $newHeaders["Authorization"] = $authHeader;
                                break;
-                                       
+                       
                        case OAuthStoreVars::$OAuthParamLocation['POST_BODY']:
                                if (! OAuthUtil::isFormEncoded($contentType)) {
                                        throw new GadgetException("Invalid 
param: OAuth param location can only " . "be post_body if post body if of type 
x-www-form-urlencoded");
@@ -333,12 +337,12 @@
                                        $postBody = $postBody . "&" . 
OAuthUtil::getPostBodyString($oauthParams);
                                }
                                break;
-                                       
+                       
                        case OAuthStoreVars::$OAuthParamLocation['URI_QUERY']:
                                $url = OAuthUtil::addParameters($url, 
$oauthParams);
                                break;
                }
-               $postBodyBytes = ($postBody == null) ? null : null 
;//$postBody->getBytes("UTF-8"); //See what can we do with this?
+               $postBodyBytes = ($postBody == null) ? null : null; 
//$postBody->getBytes("UTF-8"); //See what can we do with this?
                $rcr = new RemoteContentRequest($url);
                $rcr->createRemoteContentRequest($method, $url, $newHeaders, 
$postBodyBytes, $options);
                return $rcr;
@@ -349,7 +353,7 @@
         */
        private function sendOAuthMessage(OAuthRequest $request)
        {
-               $rcr = 
$this->createRemoteContentRequest($this->filterOAuthParams($request), 
$request->get_normalized_http_method(), $request->get_url(), null, 
RemoteContentRequest::$DEFAULT_CONTENT_TYPE, null, 
RemoteContentRequest::$DEFAULT_OPTIONS);
+               $rcr = 
$this->createRemoteContentRequest($this->filterOAuthParams($request), 
$request->get_normalized_http_method(), $request->get_url(), null, 
RemoteContentRequest::$DEFAULT_CONTENT_TYPE, null, 
RemoteContentRequest::getDefaultOptions());
                $content = $this->getNextFetcher()->fetchRequest($rcr);
                $reply = OAuthRequest::from_request();
                $params = OAuthUtil::decodeForm($content->getResponseContent());


Reply via email to