Viewing file: Abstract.php (10.23 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/** * Licensed to Jasig under one or more contributor license * agreements. See the NOTICE file distributed with this work for * additional information regarding copyright ownership. * * Jasig 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. * * PHP Version 5 * * @file CAS/ProxiedService/Http/Abstract.php * @category Authentication * @package PhpCAS * @author Adam Franco <afranco@middlebury.edu> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://wiki.jasig.org/display/CASC/phpCAS */
/** * This class implements common methods for ProxiedService implementations included * with phpCAS. * * @class CAS_ProxiedService_Http_Abstract * @category Authentication * @package PhpCAS * @author Adam Franco <afranco@middlebury.edu> * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://wiki.jasig.org/display/CASC/phpCAS */ abstract class CAS_ProxiedService_Http_Abstract extends CAS_ProxiedService_Abstract implements CAS_ProxiedService_Http { /** * The HTTP request mechanism talking to the target service. * * @var CAS_Request_RequestInterface $requestHandler */ protected $requestHandler;
/** * The storage mechanism for cookies set by the target service. * * @var CAS_CookieJar $_cookieJar */ private $_cookieJar;
/** * Constructor. * * @param CAS_Request_RequestInterface $requestHandler request handler object * @param CAS_CookieJar $cookieJar cookieJar object * * @return void */ public function __construct (CAS_Request_RequestInterface $requestHandler, CAS_CookieJar $cookieJar) { $this->requestHandler = $requestHandler; $this->_cookieJar = $cookieJar; }
/** * The target service url. * @var string $_url; */ private $_url;
/** * Answer a service identifier (URL) for whom we should fetch a proxy ticket. * * @return string * @throws Exception If no service url is available. */ public function getServiceUrl () { if (empty($this->_url)) { throw new CAS_ProxiedService_Exception('No URL set via '.get_class($this).'->setUrl($url).'); }
return $this->_url; }
/********************************************************* * Configure the Request *********************************************************/
/** * Set the URL of the Request * * @param string $url url to set * * @return void * @throws CAS_OutOfSequenceException If called after the Request has been sent. */ public function setUrl ($url) { if ($this->hasBeenSent()) { throw new CAS_OutOfSequenceException('Cannot set the URL, request already sent.'); } if (!is_string($url)) { throw new CAS_InvalidArgumentException('$url must be a string.'); }
$this->_url = $url; }
/********************************************************* * 2. Send the Request *********************************************************/
/** * Perform the request. * * @return void * @throws CAS_OutOfSequenceException If called multiple times. * @throws CAS_ProxyTicketException If there is a proxy-ticket failure. * The code of the Exception will be one of: * PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE * PHPCAS_SERVICE_PT_FAILURE * @throws CAS_ProxiedService_Exception If there is a failure sending the * request to the target service. */ public function send () { if ($this->hasBeenSent()) { throw new CAS_OutOfSequenceException('Cannot send, request already sent.'); }
phpCAS::traceBegin();
// Get our proxy ticket and append it to our URL. $this->initializeProxyTicket(); $url = $this->getServiceUrl(); if (strstr($url, '?') === false) { $url = $url.'?ticket='.$this->getProxyTicket(); } else { $url = $url.'&ticket='.$this->getProxyTicket(); }
try { $this->makeRequest($url); } catch (Exception $e) { phpCAS::traceEnd(); throw $e; } }
/** * Indicator of the number of requests (including redirects performed. * * @var int $_numRequests; */ private $_numRequests = 0;
/** * The response headers. * * @var array $_responseHeaders; */ private $_responseHeaders = array();
/** * The response status code. * * @var string $_responseStatusCode; */ private $_responseStatusCode = '';
/** * The response headers. * * @var string $_responseBody; */ private $_responseBody = '';
/** * Build and perform a request, following redirects * * @param string $url url for the request * * @return void * @throws CAS_ProxyTicketException If there is a proxy-ticket failure. * The code of the Exception will be one of: * PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE * PHPCAS_SERVICE_PT_FAILURE * @throws CAS_ProxiedService_Exception If there is a failure sending the * request to the target service. */ protected function makeRequest ($url) { // Verify that we are not in a redirect loop $this->_numRequests++; if ($this->_numRequests > 4) { $message = 'Exceeded the maximum number of redirects (3) in proxied service request.'; phpCAS::trace($message); throw new CAS_ProxiedService_Exception($message); }
// Create a new request. $request = clone $this->requestHandler; $request->setUrl($url);
// Add any cookies to the request. $request->addCookies($this->_cookieJar->getCookies($url));
// Add any other parts of the request needed by concrete classes $this->populateRequest($request);
// Perform the request. phpCAS::trace('Performing proxied service request to \''.$url.'\''); if (!$request->send()) { $message = 'Could not perform proxied service request to URL`'.$url.'\'. '.$request->getErrorMessage(); phpCAS::trace($message); throw new CAS_ProxiedService_Exception($message); }
// Store any cookies from the response; $this->_cookieJar->storeCookies($url, $request->getResponseHeaders());
// Follow any redirects if ($redirectUrl = $this->getRedirectUrl($request->getResponseHeaders())) { phpCAS :: trace('Found redirect:'.$redirectUrl); $this->makeRequest($redirectUrl); } else {
$this->_responseHeaders = $request->getResponseHeaders(); $this->_responseBody = $request->getResponseBody(); $this->_responseStatusCode = $request->getResponseStatusCode(); } }
/** * Add any other parts of the request needed by concrete classes * * @param CAS_Request_RequestInterface $request request interface object * * @return void */ abstract protected function populateRequest (CAS_Request_RequestInterface $request);
/** * Answer a redirect URL if a redirect header is found, otherwise null. * * @param array $responseHeaders response header to extract a redirect from * * @return string or null */ protected function getRedirectUrl (array $responseHeaders) { // Check for the redirect after authentication foreach ($responseHeaders as $header) { if (preg_match('/^(Location:|URI:)\s*([^\s]+.*)$/', $header, $matches)) { return trim(array_pop($matches)); } } return null; }
/********************************************************* * 3. Access the response *********************************************************/
/** * Answer true if our request has been sent yet. * * @return bool */ protected function hasBeenSent () { return ($this->_numRequests > 0); }
/** * Answer the headers of the response. * * @return array An array of header strings. * @throws CAS_OutOfSequenceException If called before the Request has been sent. */ public function getResponseHeaders () { if (!$this->hasBeenSent()) { throw new CAS_OutOfSequenceException('Cannot access response, request not sent yet.'); }
return $this->_responseHeaders; }
/** * Answer HTTP status code of the response * * @return int * @throws CAS_OutOfSequenceException If called before the Request has been sent. */ public function getResponseStatusCode () { if (!$this->hasBeenSent()) { throw new CAS_OutOfSequenceException('Cannot access response, request not sent yet.'); }
return $this->_responseStatusCode; }
/** * Answer the body of response. * * @return string * @throws CAS_OutOfSequenceException If called before the Request has been sent. */ public function getResponseBody () { if (!$this->hasBeenSent()) { throw new CAS_OutOfSequenceException('Cannot access response, request not sent yet.'); }
return $this->_responseBody; }
/** * Answer the cookies from the response. This may include cookies set during * redirect responses. * * @return array An array containing cookies. E.g. array('name' => 'val'); */ public function getCookies () { return $this->_cookieJar->getCookies($this->getServiceUrl()); }
} ?>
|