TYPO3 API  SVNRelease
ParanoidHTTPFetcher.php
Go to the documentation of this file.
00001 <?php
00002 
00003 /**
00004  * This module contains the CURL-based HTTP fetcher implementation.
00005  *
00006  * PHP versions 4 and 5
00007  *
00008  * LICENSE: See the COPYING file included in this distribution.
00009  *
00010  * @package OpenID
00011  * @author JanRain, Inc. <openid@janrain.com>
00012  * @copyright 2005-2008 Janrain, Inc.
00013  * @license http://www.apache.org/licenses/LICENSE-2.0 Apache
00014  */
00015 
00016 /**
00017  * Interface import
00018  */
00019 require_once "Auth/Yadis/HTTPFetcher.php";
00020 
00021 require_once "Auth/OpenID.php";
00022 
00023 /**
00024  * A paranoid {@link Auth_Yadis_HTTPFetcher} class which uses CURL
00025  * for fetching.
00026  *
00027  * @package OpenID
00028  */
00029 class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
00030     function Auth_Yadis_ParanoidHTTPFetcher()
00031     {
00032         $this->reset();
00033     }
00034 
00035     function reset()
00036     {
00037         $this->headers = array();
00038         $this->data = "";
00039     }
00040 
00041     /**
00042      * @access private
00043      */
00044     function _writeHeader($ch, $header)
00045     {
00046         array_push($this->headers, rtrim($header));
00047         return strlen($header);
00048     }
00049 
00050     /**
00051      * @access private
00052      */
00053     function _writeData($ch, $data)
00054     {
00055         if (strlen($this->data) > 1024*Auth_OpenID_FETCHER_MAX_RESPONSE_KB) {
00056             return 0;
00057         } else {
00058             $this->data .= $data;
00059             return strlen($data);
00060         }
00061     }
00062 
00063     /**
00064      * Does this fetcher support SSL URLs?
00065      */
00066     function supportsSSL()
00067     {
00068         $v = curl_version();
00069         if(is_array($v)) {
00070             return in_array('https', $v['protocols']);
00071         } elseif (is_string($v)) {
00072             return preg_match('/OpenSSL/i', $v);
00073         } else {
00074             return 0;
00075         }
00076     }
00077 
00078     function get($url, $extra_headers = null)
00079     {
00080         if (!$this->canFetchURL($url)) {
00081             return null;
00082         }
00083 
00084         $stop = time() + $this->timeout;
00085         $off = $this->timeout;
00086 
00087         $redir = true;
00088 
00089         while ($redir && ($off > 0)) {
00090             $this->reset();
00091 
00092             $c = curl_init();
00093 
00094             if ($c === false) {
00095                 Auth_OpenID::log(
00096                     "curl_init returned false; could not " .
00097                     "initialize for URL '%s'", $url);
00098                 return null;
00099             }
00100 
00101             if (defined('CURLOPT_NOSIGNAL')) {
00102                 curl_setopt($c, CURLOPT_NOSIGNAL, true);
00103             }
00104 
00105             if (!$this->allowedURL($url)) {
00106                 Auth_OpenID::log("Fetching URL not allowed: %s",
00107                                  $url);
00108                 return null;
00109             }
00110 
00111             curl_setopt($c, CURLOPT_WRITEFUNCTION,
00112                         array(&$this, "_writeData"));
00113             curl_setopt($c, CURLOPT_HEADERFUNCTION,
00114                         array(&$this, "_writeHeader"));
00115 
00116             if ($extra_headers) {
00117                 curl_setopt($c, CURLOPT_HTTPHEADER, $extra_headers);
00118             }
00119 
00120             $cv = curl_version();
00121             if(is_array($cv)) {
00122               $curl_user_agent = 'curl/'.$cv['version'];
00123             } else {
00124               $curl_user_agent = $cv;
00125             }
00126             curl_setopt($c, CURLOPT_USERAGENT,
00127                         Auth_OpenID_USER_AGENT.' '.$curl_user_agent);
00128             curl_setopt($c, CURLOPT_TIMEOUT, $off);
00129             curl_setopt($c, CURLOPT_URL, $url);
00130             curl_setopt($c, CURLOPT_RANGE,
00131                         "0-".(1024 * Auth_OpenID_FETCHER_MAX_RESPONSE_KB));
00132 
00133             // <TYPO3-specific>
00134             if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']) {
00135                 curl_setopt($c, CURLOPT_PROXY, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']);
00136 
00137                 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel']) {
00138                     curl_setopt($c, CURLOPT_HTTPPROXYTUNNEL, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel']);
00139                 }
00140                 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']) {
00141                     curl_setopt($c, CURLOPT_PROXYUSERPWD, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']);
00142                 }
00143             }
00144             // </TYPO3-specific>
00145 
00146             curl_exec($c);
00147 
00148             $code = curl_getinfo($c, CURLINFO_HTTP_CODE);
00149             $body = $this->data;
00150             $headers = $this->headers;
00151 
00152             if (!$code) {
00153                 Auth_OpenID::log("Got no response code when fetching %s", $url);
00154                 Auth_OpenID::log("CURL error (%s): %s",
00155                                  curl_errno($c), curl_error($c));
00156                 return null;
00157             }
00158 
00159             if (in_array($code, array(301, 302, 303, 307))) {
00160                 $url = $this->_findRedirect($headers);
00161                 $redir = true;
00162             } else {
00163                 $redir = false;
00164                 curl_close($c);
00165 
00166                 $new_headers = array();
00167 
00168                 foreach ($headers as $header) {
00169                     if (strpos($header, ': ')) {
00170                         list($name, $value) = explode(': ', $header, 2);
00171                         $new_headers[$name] = $value;
00172                     }
00173                 }
00174 
00175                 Auth_OpenID::log(
00176                     "Successfully fetched '%s': GET response code %s",
00177                     $url, $code);
00178 
00179                 return new Auth_Yadis_HTTPResponse($url, $code,
00180                                                     $new_headers, $body);
00181             }
00182 
00183             $off = $stop - time();
00184         }
00185 
00186         return null;
00187     }
00188 
00189     function post($url, $body, $extra_headers = null)
00190     {
00191         if (!$this->canFetchURL($url)) {
00192             return null;
00193         }
00194 
00195         $this->reset();
00196 
00197         $c = curl_init();
00198 
00199         if (defined('CURLOPT_NOSIGNAL')) {
00200             curl_setopt($c, CURLOPT_NOSIGNAL, true);
00201         }
00202 
00203         curl_setopt($c, CURLOPT_POST, true);
00204         curl_setopt($c, CURLOPT_POSTFIELDS, $body);
00205         curl_setopt($c, CURLOPT_TIMEOUT, $this->timeout);
00206         curl_setopt($c, CURLOPT_URL, $url);
00207         curl_setopt($c, CURLOPT_WRITEFUNCTION,
00208                     array(&$this, "_writeData"));
00209 
00210         // <TYPO3-specific>
00211         if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']) {
00212             curl_setopt($c, CURLOPT_PROXY, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']);
00213 
00214             if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel']) {
00215                 curl_setopt($c, CURLOPT_HTTPPROXYTUNNEL, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyTunnel']);
00216             }
00217             if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']) {
00218                 curl_setopt($c, CURLOPT_PROXYUSERPWD, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass']);
00219             }
00220         }
00221         // </TYPO3-specific>
00222 
00223         curl_exec($c);
00224 
00225         $code = curl_getinfo($c, CURLINFO_HTTP_CODE);
00226 
00227         if (!$code) {
00228             Auth_OpenID::log("Got no response code when fetching %s", $url);
00229             return null;
00230         }
00231 
00232         $body = $this->data;
00233 
00234         curl_close($c);
00235 
00236         $new_headers = $extra_headers;
00237 
00238         foreach ($this->headers as $header) {
00239             if (strpos($header, ': ')) {
00240                 list($name, $value) = explode(': ', $header, 2);
00241                 $new_headers[$name] = $value;
00242             }
00243 
00244         }
00245 
00246         Auth_OpenID::log("Successfully fetched '%s': POST response code %s",
00247                          $url, $code);
00248 
00249         return new Auth_Yadis_HTTPResponse($url, $code,
00250                                            $new_headers, $body);
00251     }
00252 }
00253 
00254 ?>