• Main Page
  • Related Pages
  • Modules
  • Classes
  • Files
  • Examples
  • File List
  • File Members

CAS/ProxiedService/Http/Abstract.php

Go to the documentation of this file.
00001 <?php
00002 /*
00003  * Copyright � 2003-2010, The ESUP-Portail consortium & the JA-SIG Collaborative.
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  *               * Redistributions of source code must retain the above copyright notice,
00010  *                       this list of conditions and the following disclaimer.
00011  *               * Redistributions in binary form must reproduce the above copyright notice,
00012  *                       this list of conditions and the following disclaimer in the documentation
00013  *                       and/or other materials provided with the distribution.
00014  *               * Neither the name of the ESUP-Portail consortium & the JA-SIG
00015  *                       Collaborative nor the names of its contributors may be used to endorse or
00016  *                       promote products derived from this software without specific prior
00017  *                       written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00020  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
00023  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00026  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  */
00030 
00031 require_once(dirname(__FILE__).'/../Abstract.php');
00032 require_once(dirname(__FILE__).'/../Http.php');
00033 include_once(dirname(__FILE__).'/../Exception.php');
00034 include_once(dirname(__FILE__).'/../../InvalidArgumentException.php');
00035 include_once(dirname(__FILE__).'/../../OutOfSequenceException.php');
00036 
00037 
00042 abstract class CAS_ProxiedService_Http_Abstract
00043         extends CAS_ProxiedService_Abstract
00044         implements CAS_ProxiedService_Http
00045 {
00051         protected $_requestHandler;
00052         
00058         private $_cookieJar;
00059         
00067         public function __construct (CAS_RequestInterface $requestHandler, CAS_CookieJar $cookieJar) {
00068                 $this->_requestHandler = $requestHandler;
00069                 $this->_cookieJar = $cookieJar;
00070         }
00071         
00076         private $_url;
00077         
00084         public function getServiceUrl () {
00085                 if (empty($this->_url))
00086                         throw new CAS_ProxiedService_Exception('No URL set via '.get_class($this).'->setUrl($url).');
00087                 
00088                 return $this->_url;
00089         }
00090         
00091         /*********************************************************
00092          * Configure the Request
00093          *********************************************************/
00094 
00102         public function setUrl ($url) {
00103                 if ($this->hasBeenSent())
00104                         throw new CAS_OutOfSequenceException('Cannot set the URL, request already sent.');
00105                 if (!is_string($url))
00106                         throw new CAS_InvalidArgumentException('$url must be a string.');
00107                 
00108                 $this->_url = $url;
00109         }
00110         
00111         /*********************************************************
00112          * 2. Send the Request
00113          *********************************************************/
00114 
00127         public function send () {
00128                 if ($this->hasBeenSent())
00129                         throw new CAS_OutOfSequenceException('Cannot send, request already sent.');
00130                 
00131                 phpCAS::traceBegin();
00132                 
00133                 // Get our proxy ticket and append it to our URL.
00134                 $this->initializeProxyTicket();
00135                 $url = $this->getServiceUrl();
00136                 if ( strstr($url,'?') === FALSE ) {
00137                         $url = $url.'?ticket='.$this->getProxyTicket();
00138                 } else {
00139                         $url = $url.'&ticket='.$this->getProxyTicket();
00140                 }
00141                 
00142                 try {
00143                         $this->makeRequest($url);
00144                 } catch (Exception $e) {
00145                         phpCAS::traceEnd();
00146                         throw $e;
00147                 }
00148         }
00149         
00155         private $_numRequests = 0;
00156         
00162         private $_responseHeaders = array();
00163         
00169         private $_responseStatusCode = '';
00170         
00176         private $_responseBody = '';
00177         
00190         protected function makeRequest ($url) {
00191                 // Verify that we are not in a redirect loop
00192                 $this->_numRequests++;
00193                 if ($this->_numRequests > 4) {
00194                         $message = 'Exceeded the maximum number of redirects (3) in proxied service request.';
00195                         phpCAS::trace($message);
00196                         throw new CAS_ProxiedService_Exception($message);
00197                 }
00198                 
00199                 // Create a new request.
00200                 $request = clone $this->_requestHandler;
00201                 $request->setUrl($url);
00202                 
00203                 // Add any cookies to the request.
00204                 $request->addCookies($this->_cookieJar->getCookies($url));
00205                 
00206                 // Add any other parts of the request needed by concrete classes
00207                 $this->populateRequest($request);
00208                 
00209                 // Perform the request.
00210                 phpCAS::trace('Performing proxied service request to \''.$url.'\'');
00211                 if (!$request->send()) {
00212                         $message = 'Could not perform proxied service request to URL`'.$url.'\'. '.$request->getErrorMessage();
00213                         phpCAS::trace($message);
00214                         throw new CAS_ProxiedService_Exception($message);
00215                 }
00216                 
00217                 // Store any cookies from the response;
00218                 $this->_cookieJar->storeCookies($url, $request->getResponseHeaders());
00219                 
00220                 // Follow any redirects
00221                 if ($redirectUrl = $this->getRedirectUrl($request->getResponseHeaders())) {
00222                         phpCAS :: trace('Found redirect:'.$redirectUrl);
00223                         $this->makeRequest($redirectUrl);
00224                 } else {
00225                         
00226                         $this->_responseHeaders = $request->getResponseHeaders();
00227                         $this->_responseBody = $request->getResponseBody();
00228                         $this->_responseStatusCode = $request->getResponseStatusCode();
00229                 }
00230         }
00231         
00238         abstract protected function populateRequest (CAS_RequestInterface $request);
00239         
00246         private function getRedirectUrl (array $responseHeaders) {
00247                 // Check for the redirect after authentication
00248                 foreach($responseHeaders as $header){
00249                         if (preg_match('/^(Location:|URI:)\s*([^\s]+.*)$/', $header, $matches)) {
00250                                 return trim(array_pop($matches));
00251                         }
00252                 }
00253                 return null;
00254         }
00255 
00256         /*********************************************************
00257          * 3. Access the response
00258          *********************************************************/
00259         
00265         protected function hasBeenSent () {
00266                 return ($this->_numRequests > 0);
00267         }
00268 
00275         public function getResponseHeaders () {
00276                 if (!$this->hasBeenSent())
00277                         throw new CAS_OutOfSequenceException('Cannot access response, request not sent yet.');
00278                 
00279                 return $this->_responseHeaders;
00280         }
00281         
00288         public function getResponseStatusCode () {
00289                 if (!$this->hasBeenSent())
00290                         throw new CAS_OutOfSequenceException('Cannot access response, request not sent yet.');
00291                 
00292                 return $this->_responseStatusCode;
00293         }
00294 
00301         public function getResponseBody () {
00302                 if (!$this->hasBeenSent())
00303                         throw new CAS_OutOfSequenceException('Cannot access response, request not sent yet.');
00304                 
00305                 return $this->_responseBody;
00306         }
00307         
00308 }

Generated on Sun Jun 5 2011 19:05:26 for phpCAS by  doxygen 1.7.1