Zum Inhalt springen

Multidomain 404 Fehlerseiten

Erstellt am 28. April 2006 · 24 Antworten · letzte Antwort am 2. Juli 2014 · Seite 1 von 2

Tags: Frage

sunfish ·

Hallo,
typo3 Vers. 4.0 mit REALURL
Die von REALURL "abgeworfene" Fehler Seite ist sehr schlicht und enthält keinen Link zur Startseite. Siehe: class.tx_realurl.php, function decodeSpURL_throw404($msg).

Die Extension error_404_handling lässt zwar domainbezogene Fehlerseiten zu, aber sie liefert immer einen 200 Header mit. Das finden Suchmaschinen nicht sooo gut.

Typo3 bietet aber von sich aus eine versteckte recht praktikable Möglichkeit an:
Im Installationstool All Configuration unter [pageNotFound_handling] eintragen:

[FE][pageNotFound_handling] = USER_FUNCTION:typo3conf/pageNotFoundHandling.php:user_pageNotFound->pageNotFound
[FE][pageNotFound_handling_statheader] = HTTP/1.0 404 Not Found

Im Verzeichnis typo3conf legt man die Seite pageNotFoundHandling.php mit folgendendem Inhalt an.

<?php
class user_pageNotFound {
    function pageNotFound($param,$ref) {
	
	$host = $_SERVER['HTTP_X_FORWARDED_HOST'];
	$reason = $param['reasonText'];		
	
	$msg = '
	<h3>'.$reason.'</h3>
	<p>Hier geht es zur <a href="./">Startseite</a> von '.$host.'</p>
        ';		
	$filename = "http://$host/error.html" ;
	
	$filecontent = file_get_contents($filename);  
	$pagenotfound = str_replace('{msg}', $msg, $filecontent);
	echo $pagenotfound;
  }
}
?>

Nun legt man in Typo3 bei jeder Domain eine Seite mit dem Titel error an, und schreibt in einem HTML Seitenelement den Platzhalter {msg}. So ist es möglich, die Fehlerseite im Layout der jeweiligen Domain auszugeben.

Beispiel:
http://www.keine-gentechnik.de/test.html
http://www.bantam-mais.de/test.html

Die Lösung ist nicht ganz cool, aber sie funktioniert. Vielleicht ist sie ja nicht nur für unser Projekt nützlich. Verbesserungsvorschläge werden dankend entgegengenommen. ;-)

sunfish

theo ·

Ich bekomme folgende Fehlermeldung:

Warning: file_get_contents(http:///error.html): failed to open stream: Success in /html/typo3conf/pageNotFoundHandling.php on line 14

Abgesehen davon würde bestimmt ein Problem bei der Mehrsprachigkeit auftauchen, da der Pfad fest kodiert ist und kein entsprechendes Länderkürzel dynamisch eingefügt wird?

sunfish ·

Nachtrag:
Es sieht so aus, als sollte man in dem Script erst prüfen, ob $_SERVER['HTTP_X_FORWARDED_HOST'] einen Inhalt hat.

<?php
   class user_pageNotFound {
      function pageNotFound($param,$ref) {
         $host = $_SERVER['HTTP_X_FORWARDED_HOST'];
         if(!empty($host)){
              $reason = $param['reasonText'];
              $msg = '
              <h3>'.$reason.'</h3>
              <p>Hier geht es zur <a href="./">Startseite</a> von '.$host.'</p>
              ';  
              $filename = "http://$host/error.html" ;
              $filecontent = file_get_contents($filename);
              $pagenotfound = str_replace('{msg}', $msg, $filecontent);
              echo $pagenotfound;
         }
   }
}
?>

sunfish

theo ·

Parse error: parse error, unexpected T_VARIABLE in /html/typo3conf/pageNotFoundHandling.php on line 13

😉

theo ·

Bist Du Dir übrigens ganz ganz sicher, daß man nicht auch die .htaccess darauf abstimmen muß?

sunfish ·

He,he, da haben sich einige Posts überschnitten...

[Ausserdem habe ich scheinbar keine Berechtigung meine eigenen Post's zu ändern. Gibt es da einen Trick?]

Am besten überprüft man live, welche Server-Variable den gewünschten Host zurückliefert. Die Frage der Mehrsprachigkeit habe ich hier nicht. Die Lösung soll auch nur einen Ansatz bieten.

In Zeile 13 fehlte das abschliessende das Semikolon. Sorry. Ich habe das Beispiel etwas vereinfacht, daher ungetestet. ;-)

Es funktioniert bei mir ohne Änderung der .htaccess. Wollte man dort ein error-doucument eintragen, so muss das mit dem serverinternen Pfad fest verdrahtet werden. Das geht bei der Multidomain-Lösung aber nicht.

sunfish

theo ·
sunfish schrieb

[Ausserdem habe ich scheinbar keine Berechtigung meine eigenen Post's zu ändern. Gibt es da einen Trick.]

Das lag daran, daß ich sschon einen neuen abgeschickt hatte, als Du noch dabei warst, Deinen zu editieren. Dein Abspeicherwunsch kam also zu spät...

sunfish schrieb

In Zeile 13 fehlt das abschliessende das Semikolon.

Nach dem hinzufügen des Semikolons (in Zeile 12) erscheint nun gar nichts mehr, d.h. null Quelltext.
Es wird schlichtweg nicht auf die Errorseite weitergeleitet.

Aber egal. War ein netter Versuch. Werde jetzt erstmal die anderen Lösungen durchkauen, die es da noch so gibt.

just2b ·
sunfish schrieb

[Ausserdem habe ich scheinbar keine Berechtigung meine eigenen Post's zu ändern. Gibt es da einen Trick?]

postings, die eine antwort haben, kann man nicht mehr bearbeiten. Wenn wo Fehler im Code ist, schick mir das ganze einfach per PM und ich besser aus

sunfish ·

Warning: file_get_contents(http:///error.html): failed to open stream: Success in /html/typo3conf/pageNotFoundHandling.php on line 14

Guck mal bei -> http:///error.html <- sieht man schon, dass bei dir der Host offensichtlich nicht mit $_SERVER['HTTP_X_FORWARDED_HOST'] ermittelt werden kann. Werf doch mal phpinfo(); an und schau, welche Variable dir den "wirklichen" Host liefert. Ohne diese Variable kannst du ja nicht domainspezifisch das Template der Fehlerseite ziehen. Leider konnte ich beim Suchen in $GLOBALS keine TYPO3 Variable finden, die der user_function den HOST liefert. Das wäre sicherlich das Beste.

[In meiner Lösung sind die Domains faktisch alle Subdomains der Domain, auf der Typo3 liegt. Die sichtbaren Doamins kommen per mod_proxy dort an.]

woida ·

Werde jetzt erstmal die anderen Lösungen durchkauen, die es da noch so gibt.

Hab da ja auch mal was geschrieben: #329473.

Um den Host rauszubekommen würde ich halt den referer nehmen.

bernostern ·

Hi,

wollte gerade das o.g. umsetzen.
Leider bekomme ich hier:

$filecontent = file_get_contents($filename);

immer einen 500 interner Serverfehler.

Sobald ich die Adresse (also $filename) auf Google abändere klappts. Die Adresse, die im Script erzeugt wird, ist aber richtig. Habe sie per Copy&Paste gestestet.

Habe eine T3 V4.0 Umgebung mit TV und RealURL mit mehreren Domains und ich leite per .htaccess ein paar Domains auf meine Hauptdomain um (steht alles in der .htaccess in der auch die RealURL Direktiven stehen).

Was klappt hier nicht?

Schöne Grüße,
Bern

sunfish ·

Hallo,

hier ist ein etwas modifiziertes Script, das einige Fehler, die bisher aufgetaucht sind abfangen sollte. Für bestimmte Domains ist der Text auf Englisch. Etwas Ähnliches ließe sich sicherlich auch mit "Sprachunterverzeichnissen" erreichen. Auf den von Typo3 angeboteten Fehlertext ($param['reasonText']) wird verzichtet. 😉

<?php
class user_pageNotFound {

   function pageNotFound($param,$ref) {	

   header('HTTP/1.0 404 Not Found');
   $host = '';
   
   if(!empty($_SERVER['HTTP_X_FORWARDED_HOST'])){
      $host = $_SERVER['HTTP_X_FORWARDED_HOST'];
   }
   else if(!empty($_SERVER['HTTP_HOST'])){   
      $host = $_SERVER['HTTP_HOST'];
   }
   
		
   if (!empty($host)){
      $page = $GLOBALS['_ENV']['REQUEST_URI'];
			
      $english = array('www.gmo-free-regions.org','www.genet-info.org','www.saveourseeds.org');
			
      if (in_array($host,$english)) { 
		
         $msg = '
         <h3>Sorry, the page <em> '. $page .' </em> you requested could not be found.</h3>
         <p class="top_1"><a href="./">» Here you can go to the home page of '. $host .' </a></p>
         ';
      } else {
         $msg = '
         <h3>Die aufgerufene Seite <em> '. $page .' </em> kann nicht gefunden werden.</h3>
         <p class="top_1"><a href="./">» Hier geht es zur Startseite von '. $host .'</a></p>
         ';	   
      }		
	
			
      $filename = "http://$host/error.html" ;
		
      $handle = fopen($filename, "r");
      if ($handle) {
         $filecontent = '';
         while (!feof($handle)) {
            $filecontent .= fgets($handle, 4096);
         }
         fclose($handle);       
		   
         $pagenotfound = str_replace('{msg}', $msg, $filecontent);
         echo $pagenotfound;
	  } //if ($handle)
	  else echo '<h2>SCRIPT-ERROR: Error-File '.$filename.' cannot be found.</h2>';
   } // if (!empty($host))
   	  else echo '<h2>SCRIPT-ERROR: No variable for the host (e.g. www.test.com) could be found.</h2>';
   } // function
} // class
?>

Vielleicht hilft das ja schon mal weiter?

mstuebner ·
bernostern schrieb

Sobald ich die Adresse (also $filename) auf Google abändere klappts.

$filename ist ein DATEINAME keine Domain. Was hat Google damit zu tun?

bernostern ·

@mstuebner:
$filename kann auch ein URL sein.
Daher der Scherz mit Google, also zum Test ob es am Script oder der URL liegt.

@sunfish:
Es funkt leider immer noch nicht. Mit Google nach wie vor ohne Probleme. Ich hab nun auch versucht, RealURL rauszulassen bzw. andere Konstellationen zu testen:

$filename = "http://$host/index.php?id=345";
$filename = "http://meinedomain.tld/index.php?id=345";
$filename = "http://andredomain-gleichesTypo3.tld/error.html";

345 ist die ID der Error-Seite, $host wird auch richtig aufgelöst. Nur sobald ich mit fopen (bzw. fgets, file_get_contents) versuche einen URL von meinem Server zu lesen, kommt ein 500er Error.

Das ist die Error-Log vom Apachen2:

[Fri Jul 28 16:08:01 2006] [error] [client 84.171.45.112] FastCGI: comm with server "/var/www/fcgi/cms/fcgi-starter" aborted: idle timeout (30 sec)
[Fri Jul 28 16:08:01 2006] [error] [client 84.171.45.112] FastCGI: incomplete headers (0 bytes) received from server "/var/www/fcgi/cms/fcgi-starter"
[Fri Jul 28 16:08:02 2006] [error] [client 202.12.145.20] FastCGI: comm with server "/var/www/fcgi/cms/fcgi-starter" aborted: idle timeout (30 sec)
[Fri Jul 28 16:08:02 2006] [error] [client 202.12.145.20] FastCGI: incomplete headers (0 bytes) received from server "/var/www/fcgi/cms/fcgi-starter"
[Fri Jul 28 16:08:03 2006] [warn] FastCGI: server "/var/www/fcgi/cms/fcgi-starter" (pid 4238-) terminated due to uncaught signal '11' (Segmentation fault)
[Fri Jul 28 16:08:03 2006] [warn] FastCGI: server "/var/www/fcgi/cms/fcgi-starter" has remained running for more than 30 seconds, its restart interval has been restored to 5 seconds
[Fri Jul 28 16:08:03 2006] [warn] FastCGI: server "/var/www/fcgi/cms/fcgi-starter" (uid 1000, gid 1000) restarted (pid 13163)

Meine Umgebung ist ein Debian Sarge VServer mit grsecurity-Patch und PHP als FastCGI kompiliert.

Kann mir da noch jemand nen Tipp geben?

Danke und schönes WoE,
Bern

sunfish ·

Die vorgestellte Lösung mit der Klasse "user_pageNotFound" ist nicht empfehlenswert. Fehlt die Error-Seite, in die die Fehlermeldung geparst werden soll, gerät der Server enorm unter Last, auch wenn die Klasse "user_pageNotFound" nur einmal aufgerufen wird. Offensichtlich kommt es zu einem Loop durch den rekursiven Seitenaufruf, der erst beendet wird, wenn die Script-Laufzeit überschritten wird.

Bessere Lösung für Multidomain 404 Fehlerseiten

Dmitry Dulepov und ben van 't ende haben vor längerem einen Artikel zum "Improved 404 handling" geschrieben, in dem eine einfachere und bessere Lösung vorgestellt wird.

Im Installations-Tool oder der localconf.php trägt man ([FE][pageNotFound_handling] = /http-error-404/ ein. Tritt ein 404 Fehler auf, wird in der Root der jeweiligen Domain nach einer Seite mit diesem Titel oder "Speaking URL path segment" gesucht und falls vorhanden angezeigt. Dort kann ein ganz individueller Text für die jeweilige Domain stehen. Fehlt die Seite, erscheint eine automatisch generierte typo3 Fehlermeldung, dass die Seite http-error-404 nicht gefunden wird.

Für das Error-Handling ist die Datei "typo3/sysext/cms/tslib/class.tslib_fe.php" zuständig. Unter "// Check recursion" wird mit "exit" vermieden, dass es zu einem Loop kommt, wenn die vorgesehene Seite mit der Fehlermeldung nicht gefunden wird.

Will man auf der Fehlermeldungs-Seite den vergeblich gesuchten Dateinamen ausgeben, geht das derzeit nur mit einem Hack. Denn in der "typo3/sysext/cms/tslib/class.tslib_fe.php" wird im Falle eines 404er Fehlers zum Fehler-Dokument weitergeleitet, so dass die vergeblich gesuchte Seite in keiner Globalen-Variable (t3lib_div::getIndpEnv('REQUEST_URI')) mehr zu finden ist. Als 'REQUEST_URI' steht jetzt http-error-404.

Fügt man in Zeile 1381 ein (vor: <pre>echo $content; // Output the content</pre>)

$content = str_replace('###CURRENT_URL###', t3lib_div::getIndpEnv('REQUEST_URI'), $content);

wird der Marker ###CURRENT_URL###, der im normalen Seiten Text verwendet werden kann, ersetzt.

Beispiel:
Überschrift: HTTP Fehler 404 - Seite nicht gefunden
Text: Die Seite www.meinedomain.de###CURRENT_URL### wurde nicht gefunden. Hier geht es zu unserer <link 2>Startseite</link>.

Unbekannter Benutzer ·

Vielleicht sehe ich das Problem nicht ganz, aber es geht doch viel einfacher:

Im Install-Tool nicht den Link auf irgendein Skript setzen, sondern auf eine Fehlerseite in TYPO3 (Design bleibt erhalten, nichts drumrum zu programieren usw.).
Im Template der Fehlerseite noch den richtigen Statuscode angeben und schon läuft's.

istan ·

Hallo,

das klingt eigentlich ganz einfach mit

$TYPO3_CONF_VARS['FE']['pageNotFound_handling'] = '/http-error-404/' ;
$TYPO3_CONF_VARS['FE']['pageNotFound_handling_statheader'] = 'HTTP/1.1 404 Not Found';

Ich habe auch jeweils eine Seite mit dem Seitentitel http-error-404 angelegt innerhalb der domains, aber es kommt immer die Startseite anstatt der error seite.

Wenn ich eine absolute domain angebe ala [FE][pageNotFound_handling] = http://www.domain.de/http-error-404.html , kommt die richtige seite. ich habe aber 2 domains und möchte unterschiedliche error meldungen.

sunfish ·

Hallo Istan,
Kannst du denn die Seite direkt aufrufen:
http://www.deine_domain.de/http-error-404.html
So könntest du herausfinden, ob es an der Seite selbst oder an der Weiterleitung im Fehlerfall liegt.