[ Index ]

PHP Cross Reference of Joomla 1.5.26 DE

title

Body

[close]

/libraries/openid/Auth/Yadis/ -> Yadis.php (source)

   1  <?php
   2  
   3  /**
   4   * The core PHP Yadis implementation.
   5   *
   6   * PHP versions 4 and 5
   7   *
   8   * LICENSE: See the COPYING file included in this distribution.
   9   *
  10   * @package OpenID
  11   * @author JanRain, Inc. <openid@janrain.com>
  12   * @copyright 2005-2008 Janrain, Inc.
  13   * @license http://www.apache.org/licenses/LICENSE-2.0 Apache
  14   */
  15  
  16  // Do not allow direct access
  17  defined( '_JEXEC' ) or die( 'Restricted access' );
  18  
  19  /**
  20   * Need both fetcher types so we can use the right one based on the
  21   * presence or absence of CURL.
  22   */
  23  require_once "Auth/Yadis/PlainHTTPFetcher.php";
  24  require_once "Auth/Yadis/ParanoidHTTPFetcher.php";
  25  
  26  /**
  27   * Need this for parsing HTML (looking for META tags).
  28   */
  29  require_once "Auth/Yadis/ParseHTML.php";
  30  
  31  /**
  32   * Need this to parse the XRDS document during Yadis discovery.
  33   */
  34  require_once "Auth/Yadis/XRDS.php";
  35  
  36  /**
  37   * XRDS (yadis) content type
  38   */
  39  define('Auth_Yadis_CONTENT_TYPE', 'application/xrds+xml');
  40  
  41  /**
  42   * Yadis header
  43   */
  44  define('Auth_Yadis_HEADER_NAME', 'X-XRDS-Location');
  45  
  46  /**
  47   * Contains the result of performing Yadis discovery on a URI.
  48   *
  49   * @package OpenID
  50   */
  51  class Auth_Yadis_DiscoveryResult {
  52  
  53      // The URI that was passed to the fetcher
  54      var $request_uri = null;
  55  
  56      // The result of following redirects from the request_uri
  57      var $normalized_uri = null;
  58  
  59      // The URI from which the response text was returned (set to
  60      // None if there was no XRDS document found)
  61      var $xrds_uri = null;
  62  
  63      var $xrds = null;
  64  
  65      // The content-type returned with the response_text
  66      var $content_type = null;
  67  
  68      // The document returned from the xrds_uri
  69      var $response_text = null;
  70  
  71      // Did the discovery fail miserably?
  72      var $failed = false;
  73  
  74      function Auth_Yadis_DiscoveryResult($request_uri)
  75      {
  76          // Initialize the state of the object
  77          // sets all attributes to None except the request_uri
  78          $this->request_uri = $request_uri;
  79      }
  80  
  81      function fail()
  82      {
  83          $this->failed = true;
  84      }
  85  
  86      function isFailure()
  87      {
  88          return $this->failed;
  89      }
  90  
  91      /**
  92       * Returns the list of service objects as described by the XRDS
  93       * document, if this yadis object represents a successful Yadis
  94       * discovery.
  95       *
  96       * @return array $services An array of {@link Auth_Yadis_Service}
  97       * objects
  98       */
  99      function services()
 100      {
 101          if ($this->xrds) {
 102              return $this->xrds->services();
 103          }
 104  
 105          return null;
 106      }
 107  
 108      function usedYadisLocation()
 109      {
 110          // Was the Yadis protocol's indirection used?
 111          return $this->normalized_uri != $this->xrds_uri;
 112      }
 113  
 114      function isXRDS()
 115      {
 116          // Is the response text supposed to be an XRDS document?
 117          return ($this->usedYadisLocation() ||
 118                  $this->content_type == Auth_Yadis_CONTENT_TYPE);
 119      }
 120  }
 121  
 122  /**
 123   *
 124   * Perform the Yadis protocol on the input URL and return an iterable
 125   * of resulting endpoint objects.
 126   *
 127   * input_url: The URL on which to perform the Yadis protocol
 128   *
 129   * @return: The normalized identity URL and an iterable of endpoint
 130   * objects generated by the filter function.
 131   *
 132   * xrds_parse_func: a callback which will take (uri, xrds_text) and
 133   * return an array of service endpoint objects or null.  Usually
 134   * array('Auth_OpenID_ServiceEndpoint', 'fromXRDS').
 135   *
 136   * discover_func: if not null, a callback which should take (uri) and
 137   * return an Auth_Yadis_Yadis object or null.
 138   */
 139  function Auth_Yadis_getServiceEndpoints($input_url, $xrds_parse_func,
 140                                          $discover_func=null, $fetcher=null)
 141  {
 142      if ($discover_func === null) {
 143          $discover_function = array('Auth_Yadis_Yadis', 'discover');
 144      }
 145  
 146      $yadis_result = call_user_func_array($discover_func,
 147                                           array($input_url, $fetcher));
 148  
 149      if ($yadis_result === null) {
 150          return array($input_url, array());
 151      }
 152  
 153      $endpoints = call_user_func_array($xrds_parse_func,
 154                        array($yadis_result->normalized_uri,
 155                              $yadis_result->response_text));
 156  
 157      if ($endpoints === null) {
 158          $endpoints = array();
 159      }
 160  
 161      return array($yadis_result->normalized_uri, $endpoints);
 162  }
 163  
 164  /**
 165   * This is the core of the PHP Yadis library.  This is the only class
 166   * a user needs to use to perform Yadis discovery.  This class
 167   * performs the discovery AND stores the result of the discovery.
 168   *
 169   * First, require this library into your program source:
 170   *
 171   * <pre>  require_once "Auth/Yadis/Yadis.php";</pre>
 172   *
 173   * To perform Yadis discovery, first call the "discover" method
 174   * statically with a URI parameter:
 175   *
 176   * <pre>  $http_response = array();
 177   *  $fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
 178   *  $yadis_object = Auth_Yadis_Yadis::discover($uri,
 179   *                                    $http_response, $fetcher);</pre>
 180   *
 181   * If the discovery succeeds, $yadis_object will be an instance of
 182   * {@link Auth_Yadis_Yadis}.  If not, it will be null.  The XRDS
 183   * document found during discovery should have service descriptions,
 184   * which can be accessed by calling
 185   *
 186   * <pre>  $service_list = $yadis_object->services();</pre>
 187   *
 188   * which returns an array of objects which describe each service.
 189   * These objects are instances of Auth_Yadis_Service.  Each object
 190   * describes exactly one whole Service element, complete with all of
 191   * its Types and URIs (no expansion is performed).  The common use
 192   * case for using the service objects returned by services() is to
 193   * write one or more filter functions and pass those to services():
 194   *
 195   * <pre>  $service_list = $yadis_object->services(
 196   *                               array("filterByURI",
 197   *                                     "filterByExtension"));</pre>
 198   *
 199   * The filter functions (whose names appear in the array passed to
 200   * services()) take the following form:
 201   *
 202   * <pre>  function myFilter(&$service) {
 203   *       // Query $service object here.  Return true if the service
 204   *       // matches your query; false if not.
 205   *  }</pre>
 206   *
 207   * This is an example of a filter which uses a regular expression to
 208   * match the content of URI tags (note that the Auth_Yadis_Service
 209   * class provides a getURIs() method which you should use instead of
 210   * this contrived example):
 211   *
 212   * <pre>
 213   *  function URIMatcher(&$service) {
 214   *      foreach ($service->getElements('xrd:URI') as $uri) {
 215   *          if (preg_match("/some_pattern/",
 216   *                         $service->parser->content($uri))) {
 217   *              return true;
 218   *          }
 219   *      }
 220   *      return false;
 221   *  }</pre>
 222   *
 223   * The filter functions you pass will be called for each service
 224   * object to determine which ones match the criteria your filters
 225   * specify.  The default behavior is that if a given service object
 226   * matches ANY of the filters specified in the services() call, it
 227   * will be returned.  You can specify that a given service object will
 228   * be returned ONLY if it matches ALL specified filters by changing
 229   * the match mode of services():
 230   *
 231   * <pre>  $yadis_object->services(array("filter1", "filter2"),
 232   *                          SERVICES_YADIS_MATCH_ALL);</pre>
 233   *
 234   * See {@link SERVICES_YADIS_MATCH_ALL} and {@link
 235   * SERVICES_YADIS_MATCH_ANY}.
 236   *
 237   * Services described in an XRDS should have a library which you'll
 238   * probably be using.  Those libraries are responsible for defining
 239   * filters that can be used with the "services()" call.  If you need
 240   * to write your own filter, see the documentation for {@link
 241   * Auth_Yadis_Service}.
 242   *
 243   * @package OpenID
 244   */
 245  class Auth_Yadis_Yadis {
 246  
 247      /**
 248       * Returns an HTTP fetcher object.  If the CURL extension is
 249       * present, an instance of {@link Auth_Yadis_ParanoidHTTPFetcher}
 250       * is returned.  If not, an instance of
 251       * {@link Auth_Yadis_PlainHTTPFetcher} is returned.
 252       *
 253       * If Auth_Yadis_CURL_OVERRIDE is defined, this method will always
 254       * return a {@link Auth_Yadis_PlainHTTPFetcher}.
 255       */
 256      function getHTTPFetcher($timeout = 20)
 257      {
 258          if (Auth_Yadis_Yadis::curlPresent() &&
 259              (!defined('Auth_Yadis_CURL_OVERRIDE'))) {
 260              $fetcher = new Auth_Yadis_ParanoidHTTPFetcher($timeout);
 261          } else {
 262              $fetcher = new Auth_Yadis_PlainHTTPFetcher($timeout);
 263          }
 264          return $fetcher;
 265      }
 266  
 267      function curlPresent()
 268      {
 269          return function_exists('curl_init');
 270      }
 271  
 272      /**
 273       * @access private
 274       */
 275      function _getHeader($header_list, $names)
 276      {
 277          foreach ($header_list as $name => $value) {
 278              foreach ($names as $n) {
 279                  if (strtolower($name) == strtolower($n)) {
 280                      return $value;
 281                  }
 282              }
 283          }
 284  
 285          return null;
 286      }
 287  
 288      /**
 289       * @access private
 290       */
 291      function _getContentType($content_type_header)
 292      {
 293          if ($content_type_header) {
 294              $parts = explode(";", $content_type_header);
 295              return strtolower($parts[0]);
 296          }
 297      }
 298  
 299      /**
 300       * This should be called statically and will build a Yadis
 301       * instance if the discovery process succeeds.  This implements
 302       * Yadis discovery as specified in the Yadis specification.
 303       *
 304       * @param string $uri The URI on which to perform Yadis discovery.
 305       *
 306       * @param array $http_response An array reference where the HTTP
 307       * response object will be stored (see {@link
 308       * Auth_Yadis_HTTPResponse}.
 309       *
 310       * @param Auth_Yadis_HTTPFetcher $fetcher An instance of a
 311       * Auth_Yadis_HTTPFetcher subclass.
 312       *
 313       * @param array $extra_ns_map An array which maps namespace names
 314       * to namespace URIs to be used when parsing the Yadis XRDS
 315       * document.
 316       *
 317       * @param integer $timeout An optional fetcher timeout, in seconds.
 318       *
 319       * @return mixed $obj Either null or an instance of
 320       * Auth_Yadis_Yadis, depending on whether the discovery
 321       * succeeded.
 322       */
 323      function discover($uri, &$fetcher,
 324                        $extra_ns_map = null, $timeout = 20)
 325      {
 326          $result = new Auth_Yadis_DiscoveryResult($uri);
 327  
 328          $request_uri = $uri;
 329          $headers = array("Accept: " . Auth_Yadis_CONTENT_TYPE .
 330                           ', text/html; q=0.3, application/xhtml+xml; q=0.5');
 331  
 332          if ($fetcher === null) {
 333              $fetcher = Auth_Yadis_Yadis::getHTTPFetcher($timeout);
 334          }
 335  
 336          $response = $fetcher->get($uri, $headers);
 337  
 338          if (!$response || ($response->status != 200 and
 339                             $response->status != 206)) {
 340              $result->fail();
 341              return $result;
 342          }
 343  
 344          $result->normalized_uri = $response->final_url;
 345          $result->content_type = Auth_Yadis_Yadis::_getHeader(
 346                                         $response->headers,
 347                                         array('content-type'));
 348  
 349          if ($result->content_type &&
 350              (Auth_Yadis_Yadis::_getContentType($result->content_type) ==
 351               Auth_Yadis_CONTENT_TYPE)) {
 352              $result->xrds_uri = $result->normalized_uri;
 353          } else {
 354              $yadis_location = Auth_Yadis_Yadis::_getHeader(
 355                                                   $response->headers,
 356                                                   array(Auth_Yadis_HEADER_NAME));
 357  
 358              if (!$yadis_location) {
 359                  $parser = new Auth_Yadis_ParseHTML();
 360                  $yadis_location = $parser->getHTTPEquiv($response->body);
 361              }
 362  
 363              if ($yadis_location) {
 364                  $result->xrds_uri = $yadis_location;
 365  
 366                  $response = $fetcher->get($yadis_location);
 367  
 368                  if ((!$response) || ($response->status != 200 and
 369                                       $response->status != 206)) {
 370                      $result->fail();
 371                      return $result;
 372                  }
 373  
 374                  $result->content_type = Auth_Yadis_Yadis::_getHeader(
 375                                                           $response->headers,
 376                                                           array('content-type'));
 377              }
 378          }
 379  
 380          $result->response_text = $response->body;
 381          return $result;
 382      }
 383  }
 384  
 385  ?>


Generated: Wed Mar 28 15:54:07 2012 Cross-referenced by PHPXref 0.7.1