pageNotFound_handling HTTP status fix when external URL is specified as 404 page
authorDmitry Dulepov <dmitry.dulepov@gmail.com>
Thu, 29 Jun 2006 08:05:58 +0000 (08:05 +0000)
committerDmitry Dulepov <dmitry.dulepov@gmail.com>
Thu, 29 Jun 2006 08:05:58 +0000 (08:05 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@1558 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/class.t3lib_div.php
typo3/sysext/cms/tslib/class.tslib_fe.php

index d5f4714..d28ad7e 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2006-06-29  Dmitry Dulepov  <typo3@accio.lv>
+
+       * pageNotFound_handling HTTP status fix when external URL is specified as 404 page
 
 2006-06-28  Ernesto Baschny  <ernst@cron-it.de>
 
index 3abf0e1..f54de13 100755 (executable)
@@ -2299,21 +2299,29 @@ class t3lib_div {
         * Usage: 83
         *
         * @param       string          Filepath/URL to read
-        * @param       integer         Whether the HTTP header should be fetched or not. 0=disable, 1=fetch header+content, 2=fetch header only (will be ignored when using CURL)
+        * @param       integer         Whether the HTTP header should be fetched or not. 0=disable, 1=fetch header+content, 2=fetch header only
+        * @param  array                HTTP headers to be used in the request
         * @return      string          The content from the resource given as input.
         */
-       function getURL($url, $includeHeader=0) {
-               $content = '';
+       function getURL($url, $includeHeader = 0, $requestHeaders = false)      {
+               $content = false;
 
                        // (Proxy support implemented by Arco <arco@appeltaart.mine.nu>)
-               if ((substr($url,0,7)=='http://') && ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlUse']=='1'))      {
+               if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlUse'] == '1' && preg_match('/^https?:\/\//', $url)) {
                        // External URL without error checking.
                        $ch = curl_init();
-                       if (!$ch)       { return false; }
+                       if (!$ch) {
+                               return false;
+                       }
 
-                       curl_setopt ($ch,CURLOPT_URL, $url);
-                       curl_setopt ($ch,CURLOPT_HEADER, $includeHeader?1:0);
-                       curl_setopt ($ch,CURLOPT_RETURNTRANSFER, 1);
+                       curl_setopt($ch, CURLOPT_URL, $url);
+                       curl_setopt($ch, CURLOPT_HEADER, $includeHeader ? 1 : 0);
+                       curl_setopt($ch, CURLOPT_NOBODY, $includeHeader == 2 ? 1 : 0);
+                       curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
+                       curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+                       if (is_array($requestHeaders)) {
+                               curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders);
+                       }
 
                        if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']) {
                                curl_setopt ($ch, CURLOPT_PROXY, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyServer']);
@@ -2326,36 +2334,60 @@ class t3lib_div {
                                        curl_setopt ($ch, CURLOPT_PROXYUSERPWD, $GLOBALS['TYPO3_CONF_VARS']['SYS']['curlProxyUserPass'] );
                                }
                        }
-                       $content=curl_exec ($ch);
-                       curl_close ($ch);
-
-               } elseif ($includeHeader)       {
+                       $content = curl_exec($ch);
+                       curl_close($ch);
+               } elseif ($includeHeader) {
                        $parsedURL = parse_url($url);
-                       if (!t3lib_div::inList('ftp,ftps,http,https,gopher,telnet', $parsedURL['scheme']))      { return false; }
+                       if (!t3lib_div::inList('ftp,ftps,http,https,gopher,telnet', $parsedURL['scheme'])) {
+                               return false;
+                       }
 
-                       $fp = @fsockopen($parsedURL['host'], ($parsedURL['port']>0 ? $parsedURL['port'] : 80), $errno, $errstr, $timeout=2);
-                       if (!$fp)       { return false; }
+                       $fp = @fsockopen($parsedURL['host'], ($parsedURL['port'] > 0 ? $parsedURL['port'] : 80), $errno, $errstr, 2.0);
+                       if (!$fp) {
+                               return false;
+                       }
 
-                       $msg = 'GET '.$parsedURL['path'].($parsedURL['query'] ? '?'.$parsedURL['query'] : '')." HTTP/1.0\r\nHost: ".$parsedURL['host']."\r\n\r\n";
-                       fputs ($fp, $msg);
+                       $msg = 'GET ' . $parsedURL['path'] .
+                                       ($parsedURL['query'] ? '?' . $parsedURL['query'] : '') .
+                                       ' HTTP/1.0' . chr(13) . chr(10) . 'Host: ' .
+                                       $parsedURL['host']  . chr(13) . chr(10) . chr(13) . chr(10);
+                       fputs($fp, $msg);
                        while (!feof($fp))      {
-                               $line = fgets ($fp,2048);
-                               $content.=$line;
-                               if ($includeHeader==2 && !strlen(trim($line)))  { break; }      // Stop at the first empty line (= end of header)
+                               $line = fgets($fp, 2048);
+                               $content .= $line;
+                               if ($includeHeader == 2 && !strlen(trim($line))) {
+                                       // Stop at the first empty line (= end of header)
+                                       break;
+                               }
                        }
-                       fclose ($fp);
-
-               } elseif (function_exists('file_get_contents')) {
+                       fclose($fp);
+               } elseif (is_array($requestHeaders) && function_exists('stream_context_create')) {
+                       $ctx = stream_context_create(array(
+                                                       'http' => array(
+                                                               'header' => implode(chr(13) . chr(10), $requestHeaders)
+                                                       )
+                                               )
+                                  );
+                       if (function_exists('file_get_contents')) {
+                               $content = @file_get_contents($url, $ctx);
+                       }
+                       elseif (false !== ($fd = @fopen($url, 'rb', false, $ctx))) {
+                               $content = '';
+                               while (!feof($fd))      {
+                                       $content .= fread($fd, 4096);
+                               }
+                               fclose($fd);
+                       }
+               }
+               elseif (function_exists('file_get_contents')) {
                        $content = @file_get_contents($url);
-
-               } elseif ($fd = @fopen($url,'rb'))    {
-                       while (!feof($fd))      {
-                               $content.=fread($fd, 4096);
+               }
+               elseif (false !== ($fd = @fopen($url, 'rb'))) {
+                       $content = '';
+                       while (!feof($fd))  {
+                               $content .= fread($fd, 4096);
                        }
                        fclose($fd);
-
-               } else {
-                       return false;
                }
 
                return $content;
index d48ac48..7418fcc 100755 (executable)
                        }
                        exit;
                } elseif (strlen($code)) {
-                       header('Location: '.t3lib_div::locationHeaderUrl($code));
+                       // Check if URL is relative
+                       $url_parts = parse_url($code);
+                       if ($url_parts['host'] == '') {
+                               $url_parts['host'] = t3lib_div::getIndpEnv('HTTP_HOST');
+                               $code = t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST') . $code;
+                               $checkBaseTag = false;
+                       }
+                       else {
+                               $checkBaseTag = true;
+                       }
+                       // Prepare headers
+                       $headers = array(
+                               'User-agent: ' . t3lib_div::getIndpEnv('HTTP_USER_AGENT'),
+                               'Referer: ' . t3lib_div::getIndpEnv('TYPO3_REQUEST_URL')
+                       );
+                       $content = t3lib_div::getURL($code, 0, $headers);
+                       if (false === $content) {
+                               // Last chance -- redirect
+                               header('Location: '.t3lib_div::locationHeaderUrl($code));
+                       }
+                       else {
+                               // Put <base> if necesary
+                               if ($checkBaseTag) {
+                                          // If content already has <base> tag, we do not need to do anything
+                                       if (false === stristr($content, '<base ')) {
+                                               // Generate href for base tag
+                                               $base = $url_parts['scheme'] . '://';
+                                               if ($url_parts['user'] != '') {
+                                                       $base .= $url_parts['user'];
+                                                       if ($url_parts['pass'] != '') {
+                                                               $base .= ':' . $url_parts['pass'];      
+                                                       }
+                                                       $base .= '@';
+                                               }
+                                               $base .= $url_parts['host'];
+
+                                               // Add path portion skipping possible file name
+                                               $base .= preg_replace('/(.*\/)[^\/]*/', '\1', $url_parts['path']);
+
+                                               // Put it into content (generate also <head> if necessary)
+                                               $replacement = chr(10) . '<base href="' . htmlentities($base) . '" />' . chr(10);
+                                               if (stristr($content, '<head>')) {
+                                                       $content = preg_replace('/(<head>)/i', '\1' . $replacement, $content);
+                                               }
+                                               else {
+                                                       $content = preg_replace('/(<html[^>]*>)/i', '\1<head>' . $replacement . '</head>', $content);
+                                               }
+                                  }
+                               }
+                               // Output it
+                               echo $content;
+                       }
                        exit;
                } else {
                        $this->printError('Error.'.($reason ? ' Reason: '.htmlspecialchars($reason) : ''));