Motivation
Weiter zur BeschreibungEine Website kann im Internet unter vielen Adressen erreichbar sein. Oft sind example.com und www.example.com die selbe Site. Es kann aber von Vorteil sein unter beiden Adressen erreichbar zu sein, aber in der Adresszeile des Browsers immer nur eine Adresse zu haben. Dazu könnte bei example.com eine Weiterleitung auf www.example.com eingerichtet werden.
Webserver können viele Webseiten gleichzeitig hosten. Welche Website sie liefern sollen, unterscheiden Sie anhand des angegebenen Hosts in der HTTP-Abfrage.
www.example.com — habe ich nicht!
Was macht ein Server wenn er eine Anfrage für einen Host bekommt, den er nicht kennt? In diesem Fall liefert der Server seine Standardseite. Einige der großen Webspace Anbieter haben dazu Fehlermeldungen oder Eigenwerbung als Standard eingerichtet.
Das Internet arbeitet „ intern ” mit IP-Adressen. Diese bestehen nur aus Zahlen. Um zu den bekannten Hostnamen eine IP-Adresse zu erhalten gibt es sogenannte Nameserver. Wenn Sie im Webbrowser www.richler.de eingeben, fragt dieser die dazugehörige Adresse (87.106.74.74) ab und schickt an diese Adresse seinen HTTP-Request.
Die Domänen richler.de und richler.info sind, wie viele anderen auch, so eingerichtet, dass alle Hostname auf die selbe IP-Adresse zeigen. Bei diesen beiden Domänen ist das sogar die selbe. Darum liefern invalid.richler.info und invalid.richler.de die selbe Standardseite.
Weiter schicken — aber ganz individuell
Um Besucher nicht zu verlieren soll die Standardseite Besucher auf existierende Angebote weiterleiten. Dies soll abhängig vom benutzten Hostnamen geschehen. Eine Anfrage auf invalid.richler.de soll auf www.richler.de und eine Anfrage auf not-here.richler.info auf www.richler.info geleitet werden.
Was ist checkHostname()?
Weiter zum QuellcodecheckHostname kontrolliert anhand einer angegebenen
Konfigurationsdatei was wohin umgeleitet werden soll.
Die Funktion muss aufgerufen werden bevor Teile einer Inhaltsseite (HTML) zum Client übertragen wurde. Andernfalls kann eine Weiterleitung (Redirect) nicht mehr angestoßen werden.
Im Falle einer Weiterleitung wird die Abarbeitung der Anfrage
abgebrochen. Die Funktion wird nicht mehr verlassen. Erfolgt keine
Weiterleitung liefert sie true wenn kein Bedarf an einer
Weiterleitung besteht oder false wenn eine Weiterleitung
nicht sinnvoll ist. Dies ist in der Regel dann der Fall, wenn als Ziel
die aufgerufene Adresse eingetragen ist. Sonst würde eine
Endlos-Schleife erzeugt. Manche Browser, z.B. Microsofts Internet
Explorer™ 6, erkennen so eine Schleife nicht!
Ein kleines und verbesserungswürdiges Beispiel:
1
<?php
2
3 require_once('chkHostname');
4
5 if (!checkHostname('hosts.ini')) {
6 echo 'this is an error!';
7 }
8
9 ?><html>
10 <body>
11 <h1>Welcome</h1>
12 </body>
13 </html>
Gesteuert wird die Weiterleitung durch eine Konfigurationsdatei bzw. ini-Datei. In eckigen Klammern stehen die Hostnamen und danach die dazugehörigen Parameter. Es wird immer nur die erste zutreffende Regel angewandt alle weiteren werden nicht mehr beachtet.
Im Beispiel (hosts.ini) wird in Zeile 1 eine Regel für den Hostanmen www.richler.de angelegt. Da dieser keine Parameter folgen wird keine Weiterleitung ausgeführt. Dies kann benutzt werden eine Weiterleitung für diesen Hostnamen auszuschließen.
Ab Zeile 4 ist für ww.richler.de eine Weiterleitung auf www.richler.de angegeben.
In Zeile 7 ist *.richler.de eine Regel für alle Subdomains von richler.de eingerichtet. Sie trifft auf alle Hostnamen zu die vorne beliebe Zeichen haben und mit .richler.de enden. Diese Regel würde also auch auf www.richler.de und ww.richler.de zutreffen. Da diese Namen aber schon vorher angegeben worden sind, würde die Regel *.richler.de nicht mehr erreicht.
Die Regel für für richler.de gibt mir keepquery = true an, dass die Anfrage durchgereicht werden soll. Die Adresse http://richler.de/seite.html wird also auf http://www.richler.de/seite.html weitergeleitetn. Ohne keepquery wäre das Ziel http://www.richler.de.
Das HTTP kennt zwei Arten von Weiterleitungen; Vorrübergehende und permanente. Bei permanenten Weiterleitungen können Browser oder Proxys sich die Weiterleitung merken und brauchen den Server nicht jedes mal erneut zu fragen. Aber auch Suchmaschinen benutzen diese Informationen um Permanent weitergeleitete Seiten in ihrem Index durch das Weiterleitungsziel zu ersetzen.
1 [www.richler.de]
2
; do nothing - no more rules will be checked
3
4
5
[ww.richler.de]
6
redirect = http://www.richler.de/
7
8
9
[*.richler.de]
10
redirect = http://www.richler.de/
11
12
13
[*.richler.info]
14
redirect = http://www.richler.info/
15
16
17
[richler.de]
18
redirect = http://www.richler.de
19
20
keepquery = true
21
22
permanent = true
23
24
25
; Default:
26
27
[*]
28
redirect = http://www.richler.de/
Die Funktion checkHostname()
Weiter zum Download 1
<?php
2 /*********************************************************************
3 *
4 * Reads a given ini-File and does some Redirection based on Hostnames
5 *
6 * If there is a matching rule this function will redirect to an other
7 * site. If there is no matching rule or one with no destination it
8 * returns true. If there is a matching rule but the function detects
9 * a loop it returns false.
10 *
11 * (C) 2006 by Heiko Richler http://www.richler.de/
12 *
13 * This Code is provided unter the GNU Lesser General Public License
14 * http://www.gnu.org/licenses/lgpl.html
15 *
16 * No warranty at all!
17 */
18 function checkHostname($inifile = 'hosts.ini') {
19 // Load ini-File. Each section in this file represents an
20 // Domainname to match.
21 $ini = parse_ini_file($inifile, true);
22 foreach($ini as $domain => $vArgs) {
23 // Create regular expression out of Domainname. It may
24 // contain * as a wildcard
25 $regex = '/^' . str_replace(array('.', '*'),
26 array('\.', '.*'), $domain) . '$/i';
27 if (preg_match($regex, $_SERVER['HTTP_HOST'])) {
28 if (isset($vArgs['redirect'])) {
29 $destination = $vArgs['redirect'];
30 if (isset($vArgs['keepquery']) and $vArgs['keepquery']) {
31 $destination .= $_SERVER['REQUEST_URI'].
32 $_SERVER['QUERY_STRING'];
33 }
34 $old = 'http'.
35 (($_SERVER['HTTPS'] == 'on') ? 'S' : '').
36 '://'.
37 $_SERVER['HTTP_HOST'].
38 $_SERVER['REQUEST_URI'].
39 $_SERVER['QUERY_STRING'];
40 if ($old == $destination) { // this would be a loop!
41 // error_log(...) ?
42 return false;
43 }
44 $counter = 0;
45 if (isset($_COOKIE['RedirectCounter'])) {
46 $counter = @intval($_COOKIE['RedirectCounter']);
47 }
48 if (isset($_COOKIE['Redirected'])) {
49 // I redirected from here ...
50 if ($_COOKIE['Redirected']>=time()-5) {
51 // ... and I did so within the last 5 seconds
52 // this should be a lot of time - even for a
53 // slow client
54 $counter++;
55 }
56 else {
57 // after more than 5 seconds I believe this was a
58 // reload by user
59 $counter = 0;
60 }
61 }
62 if ($counter>19) { // Firefox waits till 20 to detect a loop
63 // this may be a loop!
64 // error_log(...) ?
65 return false;
66 }
67 setcookie('Redirected',time(),time()+60); // 60 seconds
68 setcookie('RedirectCounter',$counter,time()+60); // 60 seconds
69 if (isset($vArgs['permanent']) and $vArgs['permanent']) {
70 // Use a permanent reddirect means the client may
71 // remember it and doesn't ask for the original site
72 // again soon.
73 header('HTTP/1.1 301 Moved Permanently');
74 }
75 header("Location:$destination");
76 echo "<html><body>
77 <a href='$destination'>Redirecting to $destination.</a>
78 </body></html>";
79 die(); // do nothing else
80 }
81 // No Destination to redirect to, so do nothing
82 // This can be used to set a rule without redirecting to
83 // avoid following rules to match.
84 return true;
85 }
86 }
87 // No Matching Rule
88 return true;
89 }
90 ?>
Download von chkHostname.php
Hier können Sie die Projektdateien in einem Archiv beziehen: chkHostname.zip.