HTTP Response-Header

Unsichtbarer Vorlauf jeder Webseite

102 # url=http://www.topsoft.at/pstrainer/demo/html/demo.html
Wenn ihr Browser eine Webseite anfordert, dann sendet der entsprechende Webserver vor dem HTML-Quelltext der Seite einige Zeilen Text - den HTTP Response-Header. Moderne Programmiersprachen bieten die Möglichkeit, den HTTP-Header empfangener Seiten zu analysieren (wie hier), bzw. den Header gesendeter Seiten nach Bedarf zu gestalten.
Internet Protokolle, Dienste und Services - HTTP
HTTP Grundlagen und Übersicht
Live-Header Live-Analyse der Header beliebiger Webseiten
HTTP-Felder Informationen vom Webserver an den Browser
Perl Lesen des HTTP-Headers mit Perl
PHP Lesen und Schreiben des HTTP-Headers mit PHP
Router Verbindung über einen Router / Proxy-Server hinweg
Verwandte Themen: HTML, HTTP-Request (HTTP-Anforderung), HTTP Status Code (Erfolg einer HTTP-Anfrage), Ajax (HTTP-Anforderung durch Javascript-Programme)
Links Ausgewählte HTTP-Links Links zum Thema 'HTTP-Header'

Live-Anzeige des HTTP-Headers

Die Live-Anzeige ist abgeschaltet, weil das dazu verwendete Perl-Modul LWP derzeit am Webserver nicht verfügbar ist.
Derzeit abgeschaltet... Geben sie die Adresse einer beliebigen Webseite ein und klicken sie den Button 'anzeigen'.
Der HTTP-Header der zurückgesendeten Webseite wird angezeigt.
Wenn das nicht möglich ist, erhalten sie eine "Fehler"-Webseite - ebenfalls mit HTTP-Header.
Wozu ein HTTP-Header ?
Es gibt zahlreiche verschiedene Möglichkeiten für den Inhalt eintreffender Daten-Pakete, z.B. HTML-Quelltexte, Bilder, . .
Der HTTP-Header enthält im Klartext einige Informationen, die es dem Empfangs-Programm (z.B. ihrem Browser) erleichtern sollen, die nachfolgenden Daten richtig zu verarbeiten.
Wer sendet den HTTP-Header ?
Man erhält auf fast jede Anfrage an einen Webserver als Antwort eine Webseite (mit HTTP-Header):
Wenn die gewünschte Datei (Webseite) existiert, sendet der adressierte Webserver den HTTP-Header und die angeforderten Daten.
Andernfalls sendet der Webserver - wenn er überhaupt erreicht wurde - eine Webseite mit Fehler-Meldung.
Wenn der zutreffende Webserver nicht gefunden wird, erhalten sie eine Fehlerseite (Timeout) von ihrem Proxy-Server oder von ihrem Browser.
Wenn der Ziel-Server erfolgreich erreicht wird, dieser jedoch das gewünschte Ziel nicht findet, dann erhalten sie die Fehler-Seite vom Ziel-Server.
Bedenken sie diese Möglichkeiten, wenn sie Webseiten automatisch auswerten.
Was bedeutet die erste Zeile ?
Jeder HTTP Header enthält in der ersten Text-Zeile das Protokoll (HTTP-Version) und den → HTTP Status (Response) Code.

Der HTTP Status Code ist ein standardisierter Zahlencode, welcher den Erfolg der Browser-Anfrage mitteilt, z.B. OK oder verschiedene Fehler-Meldungen.
Details zum HTTP Status Code
Was bedeutet 'Arbeitszeit' ?
Das Programm misst die Zeit vom Absenden des HTTP-Requests bis zum Ende der eingetroffenen Daten.
Diese 'Round trip time' beträgt im lokalen Netzwerk (LAN) typisch 10..100 ms, im Internet je nach Verbindung, Auslastung usw. 1..10 s
Wenn nach 10 Sekunden noch keine Daten eingetroffen sind (Timeout), beendet das Programm seine Arbeit.
Kontrolle: Sie können die Web-Adresse (URL) in der eingebetteten Seite anklicken, um die Webseite selbst dort zu laden.

Felder des HTTP-Headers

Ein HTTP-Header bietet Platz für sehr viele verschiedene Angaben. Je nach Server (und Programmierung) sind darin teilweise unterschiedliche Informationen enthalten. Die Verwendung dieser Daten für eigene Programme ist daher problematisch.
Der Header enthält Variable (Felder) in dieser Form:
Feldname: Feldwert
Jedes Feld beginnt mit einer neuen Zeile.
Die nachfolgende Reihung nach Häufigkeit (in %) ergab sich aus einer Analyse der HTTP-Header zufällig angeforderter Webseiten.
Automatisch arbeitende Programme (Spider, Bot, Crawler...) lassen sich leicht mit → Perl oder → PHP erstellen: Sie 'lesen' z.B. Webseiten und folgen den darin enthaltenen Links, um weitere Webseiten zu analysieren ... )

Meistens (>90%) enthaltene Felder:

Nur Felder mit hoher Wahrscheinlichkeit können für die Auswertung herangezogen werden. Man sollte sich allerdings niemals darauf verlassen, dass sie in jedem HTTP-Header enthalten sind.

Diese 3 Client-Felder enthalten nur Daten, die einem anfragenden Programm ohnehin bekannt sein sollten:
Client-Date Datum & Zeit am anfragenden PC
Client-Peer Adresse und Port des anfragenden PC (d.h. ihres eigenen PC oder ihres Proxy-Servers).
Client-Response-Num normalerweise = 1

Content-Type beschreibt → MIME-Type bzw. → Zeichensatz (für Texte) der nachfolgenden Daten.
Date Datum & Zeit am Server, immer in GMT (d.h. Weltzeit UTC). Bietet bei verlässlichen Servern die Möglichkeit der → Zeit-Synchronisation.
Server Kennung des Servers. Uneinheitlicher Text, kaum für Programme verwendbar.
Connection kündigt an, was mit der Verbindung nach dem Senden der Daten passiert. Der Wert ist meist close, d.h. die Verbindung wird danach geschlossen.

Häufige Felder (>40%):

Content-Length) Länge der nachfolgenden Daten in Byte. Der größte Teil umfangreicher Webseiten entfällt auf darin als Verweis enthaltene Bilder, Sounds, Animationen. Diese werden vom Browser nach dem Laden der der 'gastgebenden' Webseite angefordert - Das kann auch ihr Programm (Perl, PHP, ..) tun oder z.B. überlange Daten zurückweisen.

Last-Modified Letzte Änderung der nachfolgenden Daten - Ihr Programm kann nachfragen, ob die Daten seit dem letzten Zugriff geändert wurden.
Accept-Ranges Bereitschaft des Servers, Bereichs-Anfragen anzunehmen
Etag Entity-Tag (selten wirklich verwendet, Beschreibung bei W3C)

Gelegentlich (>20%) anzutreffende Felder:

Cache-Control, X-Powered-By, Set-Cookie, Expires

Seltene Felder (<10%):

Pragma, P3P, Vary, Cache-Directive, Content-Language, Pragma-Directive, X-Pingback, ...
Hinweis: Fehler-Webseiten enthalten normalerweise in ihrem HTTP-Header nur wenige Felder !

HTTP-Header mit Perl

Alle gängigen Programmiersprachen bieten die Möglichkeit, eine Verbindung (socket) zu einem entfernten Dienst (z.B. zu einem Webserver über das Internet) aufzunehmen.
Hier werden Scripts in der Programmiersprache → Perl verwendet, welche die Daten (s.o.) als 'Dynamische Webseiten' live anzeigen.
Das Programm befindet sich am Webserver, fordert von dort aus (!) die gewünschte Webseite an, analysiert sie und sendet das Ergebnis (den Text des HTTP-Headers) als Webseite an ihren Browser. Die vom Script erzeugte Webseite wird als <iframe> (oben, weiss unterlegt) in diese Webseite eingebettet.
Details zum Lesen von Webseiten mit Javascript-, Perl- oder PHP-Programmen.
Rechts das verwendete Perl Script-Programm (vereinfacht):

Die erste Zeile des Scripts muss einen Verweis auf das Perl-Interpreter-Programm enthalten. Löschen/Ändern sie nach Bedarf.
Das Modul LWP enthält alle Methoden für socket-Verbindungen. Details finden sie im Internet und in der ausführlichen Perl-Dokumentation.
Details zum → Lesen von Webseiten mit Perl
Die Adresse der gewünschten Webseite wird als Argument 'url' an die Variable $url des Script-Programms übergeben.
Falls der ausführende Computer (hier: der Webserver) direkten Zugang zum Internet hat, bleibt Variable $myproxy leer. Andernfalls tragen sie hier die Adresse ihres Proxy-Servers ein.
Zur Ausführung wird ein 'user agent' ($ua) erzeugt. Im Request wird der HEAD angefordert (alternativ können sie mit GET die Webseite selbst anfordern).
Bei Erfolg (is_success) wird der Text des HTTP-Headers angezeigt, bei Misserfolg die Fehlermeldung.
Mit einem → Regulären Ausdruck wird der Zeilen-Umbruch HTML-gerecht geändert.
Der Text des HTTP-Headers befindet sich in der Variablen $text und kann natürlich an Stelle der Ausgabe auch anders verarbeitet werden.
#! /usr/bin/perl
#! c:\perl\bin\perl.exe
########## Perl Module ##########
use CGI;
use LWP;
########## Ausgabe auf Webseite ##########
print "Content-type: text/html\n\n";
print "<html>\n";
print "<head><title>HTTP-Header</title></head>\n";
print "<body>\n";
########## Parameter ##########
my $myq = new CGI;
my $url="";
$url = $myq->param('url');
########## Proxy ##########
my $myproxy="";
# $myproxy="http://192.168.0.1:2345/";
########## Ausfuehrung ##########
my $ua = LWP::UserAgent->new();
if(length($myproxy)) {$ua->proxy(http => $myproxy);}
my $request = HTTP::Request->new('HEAD',$url);
my $response = $ua->request($request);
if($response->is_success()) {
my $text=$response->headers_as_string();
$text=~s/\n/<br>\n/g;
print "$text\n";
}
else {print $response->message();}
print "<br>\n";
print "</body>\n</html>\n";
Sie können das Script mit geringen Änderungen auch als (System-unabhängiges !) → Konsolen-Script verwenden.

In diesem Fall fällt das Modul CGI weg, die Web-Adresse wird als Commandline - Argument $ARGV übergeben.
Alle HTML-tags werden aus den print-Anweisungen entfernt.
Dieses Programm erfordert die korrekte Installation der (kostenlosen) Programmiersprache → Perl.
Das Programm wird (je nach Installation) so gestartet:
Linux:
# http_header.pl http://www.topsoft.at/pstrainer/demo/html/demo.html
Windows (Varianten):
C:\> C:\perl\bin\perl.exe c:\http_header.pl http://www.topsoft.at/pstrainer/demo/html/demo.html
C:\> perl.exe http_header.pl http://www.topsoft.at/pstrainer/demo/html/demo.html
C:\> http_header.pl http://www.topsoft.at/pstrainer/demo/html/demo.html
#! /usr/bin/perl
#! c:\perl\bin\perl.exe
########## Perl Module ##########
use LWP;
########## Ausgabe auf Konsole ##########
print "HTTP-Header\n";
########## Runtime-Argumente ##########
my $url = $ARGV[0] || "http://pstrainer.topsoft.at/";
########## Proxy ##########
my $myproxy="";
# $myproxy="http://192.168.0.1:2345/";
########## Ausfuehrung ##########
my $ua = LWP::UserAgent->new();
if(length($myproxy)) {$ua->proxy(http => $myproxy);}
my $request = HTTP::Request->new('HEAD',$url);
my $response = $ua->request($request);
if($response->is_success()) {
print $response->headers_as_string();
}
else {print $response->message();}
print "\n";
Wenn nur bestimmte Felder aus dem HTTP-Header benötigt werden (z.B. die Server-Zeit s.o.), dann ist eine andere Version vorteilhafter:
Der HTTP-Header wird an eine Variable (hier $hdr) zugewiesen, danach sind seine Bestandteile verfügbar:
headers_as_string liefert den gesamten Header als String
date liefert die Header-Variable 'Date'. Das Ergebnis ist ein UNIX-Timestamp ($uts) und kann mit üblichen → Datum-&-Zeit Methoden verarbeitet werden.
server liefert die Kennung des Webservers
usw. usw.
$hdr = $ua->head($refurl);
$text = $hdr->headers_as_string();
$uts = $hdr->date+0;
$server = $hdr->server;
# usw. usw.
Wenn sie ein → Konsolen-Script dazu verwenden, die Systemzeit ihres PC zu setzen, dann können sie dazu die Funktion system verwenden.
Sehen sie rechts, wie der entsprechende Systembefehl auf → Linux oder → Windows formuliert wird.
# Linux
$shellcmd = "date --set=$mytim";
# Windows
$shellcmd = "time $mytim";
# Systembefehl
system($shellcmd);
Details zum Lesen von Webseiten mit Javascript-, Perl- oder PHP-Programmen.

HTTP-Header mit PHP

Funktion   get_headers()

Das PHP-Modul standard enthält ab Version 5 die Funktion get_headers()
Allerdings ist diese Funktion bei manchen Providern abgeschaltet. ( → PHP-Umgebung / disable_functions)
Live PHP Version:
phpversion() = 5.3.3-7+squeeze9
Live PHP Modul-Test:
PHP-Funktion get_headers ist verfügbar.
Anwendung der Funktion get_headers()
Damit wird der HTTP Header einer Webserver-Antwort gelesen und ausgegeben.
php_function_get_headers Diese Funktion ist derzeit wahrscheinlich die beste und einfachste zur Analyse des HTTP-Headers:
Der gesamte HTTP-Header ohne Einschränkung wird als Array zeilenweise zurückgegeben.

Die Daten enthalten die wichtige HTTP-Start-Zeile mit dem numerischen und verbalen Antwort-Code:.
Eine korrekte Webseite wird so angekündigt:
HTTP/1.1 200 OK
Eine typische Fehlerseite wird mit jedem anderen → HTTP Status-Code angekündigt:
HTTP/1.1 404 Not Found

Die Daten enthalten meistens die Variable Date und damit die aktuelle Zeit des Servers. Man kann sie daher u.a. zur bequemen Synchronisation der eigenen Systemzeit verwenden.

Die Variablen sind in je einer ganze Zeile organisiert, die man selbst in Name und Wert trennen muss.

Man kann als Argument beliebige URLs eingeben, d.h. von Webseiten auf eigenen und fremden Servern, von Bildern oder anderen Objekten, sogar von nicht vorhandenen Objekten (das provoziert die Fehler-Antwort des Servers).
HTTP-Header mit PHP lesen:
Elegant und einfach:
$url = 'http://www.topsoft.at/pstrainer/demo/html/demo.html';
$hdr = get_headers($url);
foreach($hdr as $v) {
print "$v <br />";
}
Live-Ausgabe des PHP-Programmbeispiels get_headers für die Webseite http://www.topsoft.at/pstrainer/demo/html/demo.html
PHP-Funktion get_headers() ist verfügbar.
Bei Ausführung der Funktion trat jedoch ein Fehler auf.
(Keine Verbindung, Behinderung durch Firewall, ... ?

Funktion   apache_response_headers()

Mit dieser PHP-Funktion wird der HTTP-Header analysiert, welcher den 'Antwort'-Daten des Webservers vorausgeht.
Die Daten werden in einem assoziativen Array zurückgegeben, d.h. sauber getrennt in Name und Wert.
Diese Funktion liefert leider nicht alle Header-Variablen, insbesondere nicht Datum und Zeit des Webservers.
In der Live-Ausgabe (unten) des Beispiels finden sie jenen HTTP-Header, den der Webserver als Ankündigung der jetzt angezeigten Webseite an ihren Browser gesendet hat.
Ein HTTP-Header wird auch vor anderen Dateien gesendet, z.B. vor Bildern - In diesem Fall wird jedoch mit Content-Type eine andere → MIME-Type angekündigt (für Bilder z.B. image/gif, image/jpeg, image/png,..).
$arh = apache_response_headers();
foreach ($arh as $h=>$v) {
print "$h: $v<br />\n";
}
Live-Ausgabe des PHP-Programmbeispiels apache_response_headers für die Webseite http://www.topsoft.at/pstrainer/demo/html/demo.html
Funktion apache_response_headers ist nicht verfügbar !

Schreiben von HTTP-Header Variablen

Alle gängigen Server-Programmiersprachen (→ Perl, → PHP, ..) bieten die Möglichkeit, den HTTP-Header einer am Server erzeugten Datei zu beeinflussen. Das ist z.B. sinnvoll, wenn nicht sichergestellt ist, dass der Webserver die gewünschte → MIME-Type anzeigt.
Die PHP-Funktion header() bietet diese Möglichkeit.
Im Beispiel rechts wird die MIME-Type der nachfolgenden Datei in der HTTP-Variablen Content-type mit application/xhtml+xml (→ XHTML) festgelegt.
Funktion header kann beliebig oft aufgerufen werden, um mehrere HTTP-Header Variablen zu schreiben.
Funktion header muss vor Beginn des eigentlichen Dokuments aufgerufen werden, da sonst der HTTP-Header an dieser Stelle bereits automatisch erzeugt und evtl. sogar abgesendet wurde.
<?php
  header("Content-type: application/xhtml+xml");
?>
<?xml version="1.0" standalone="no"?>
<html xmlns="http://www.w3.org/1999/xhtml">
...
</html>

Bekanntgabe der MIME-Type

Server-Programmiersprachen (→ Perl, → PHP, ..) sind in der Lage, einen direkten Datenstrom an den Webserver zu senden.
Das wird z.B. für dynamische Grafik verwendet, wenn das angeforderte Dokument nur individuelle Bedeutung hat und daher nicht gespeichert wird.
In diesem Fall verzichtet man darauf, eine Datei zu erzeugen und diese an den Browser zu senden, sondern der Datenstrom läuft direkt vom Script-Programm zum Webserver und weiter zum Browser.
Ein Datenstrom muss an seinem Anfang die beiden rechts gezeigten Zeilen enthalten. (Die 2. Zeile ist eine Leerzeile)
Daraus erstellt der Webserver automatisch den HTTP-Header mit der angegebenen → MIME-Type.
Erst danach folgt der eigentliche Datenstrom an den Browser.
Anfang eines HTML-Datenstroms:
print "Content-type: text/html\n\n";
print "<html>";

Anfang eines Grafik-Datenstroms:
print "Content-type: image/png\n\n";

Router / Proxy-Server

Die Programmierung von Verbindungen ist aufwändiger, wenn sich das Programm an einem → Webserver im eigenen lokalen Netzwerk (LAN) befindet und das Ziel im Internet.
In diesem Fall muss die Verbindung über den zuständigen → Router / Proxy-Server laufen.
Der Router muss an einer fixen Adresse erreichbar sein. Diese ist durch IP-Adresse und Port festgelegt, z.B. 192.168.0.1:8080
In größeren Netzwerken verlangt der Router zusätzlich eine Authentifizierung (meist mit Name + Passwort).
Man muss Maßnahmen treffen, um die Zugangs-Daten an alle Programme auf allen Geräten (PC) des LAN zu leiten, die mit dem Internet in Verbindung treten sollen.

Umgebungs-Variable des Betriebssystems

Die Standard-Methode zur Verwaltung der Proxy-Zugangsdaten sind Umgebungs-Variable. Mindestens am Server sollten die hier vorgestellten Variablen definiert sein (die angegebenen Werte sind Beispiele - setzen sie ihre eigenen Daten ein):
FTP_PROXY="http://192.168.0.1:8080"
HTTP_PROXY="http://192.168.0.1:8080"
HTTPS_PROXY="http://192.168.0.1:8080"
NO_PROXY="localhost, 127.0.0.1, 192.168.0.0/24"
Allfällige Authentifizierungs-Daten des Routers:
HTTP_PROXY_USER="ich"
HTTP_PROXY_PASS="geheim"

Die Namen der Variablen können auch in kleinen Buchstaben bezeichnet sein (z.B. http_proxy). Da Linux streng unterscheidet, ist es empfehlenswert, die Variablen in je einer Version mit großen und mit kleinen Buchstaben anzulegen, aber natürlich mit den gleichen Werten.
Es ist sehr empfehlenswert, diese Umgebungs-Variablen auch auf einem Windows-Server anzulegen (nur in Großbuchstaben), da sich daran viele (Opensource) Programme orientieren.
Details zu → Windows Umgebungs-Variablen

Apache Webserver

Die Standard-Konfiguration des Apache Servers gibt die erwähnten Umgebungs-Variablen aus Sicherheits-Gründen nicht an Server-Programme weiter. Am eigenen LAN-Server besteht normalerweise kein Risiko, d.h. man kann diese Daten an die am eigenen Server innerhalb des LAN laufenden Programme weitergeben.

Apache-Modul   mod_env
Dieses Modul muss geladen werden. Details dazu finden sie in der Konfiguration der jeweiligen Distribution. Kontrolle mit einem Browser am Server-PC mit dieser URL (wenn eingerichtet): http://localhost/server-info
Manual (wenn eingerichtet):
http://localhost/manual

Konfigurations-Datei:
Diese Anweisungen sollten in eine der Konfigurations-Dateien eingetragen werden, noch besser in eine eigene Datei environment.conf
<IfModule mod_env.c>
PassEnv FTP_PROXY
PassEnv HTTP_PROXY
PassEnv NO_PROXY
</IfModule>
Damit werden die bezeichneten Umgebungs-Variablen weitergeleitet. Weniger empfehlenswert ist es, die Variablen-Werte direkt einzusetzen, z.B. mit
SetEnv HTTP_PROXY "192.168.0.1:8080"

Jede Änderung der Konfiguration wird erst nach Neustart des Webservers wirksam.

Umgebungs-Variable in Programmen

Ein Programm erhält seine Umgebungs-Variablen prinzipiell von seinem Parent (Caller, ...), d.h. von jenem Programm, von dem es gestartet wurde. Das gleiche Programm (z.B. test.pl) erhält unterschiedliche Daten, wenn es z.B. manuell an einer Shell-Konsole gestartet wurde, oder vom Webserver als CGI-Programm, oder vom Cron-Server (Zeit-gesteuert). Es kann verwirrend sein, wenn ein an der Konsole getestetes Programm nicht mehr funktioniert, wenn es vom Webserver verwendet wird.

Jede moderne Programmiersprache bietet Zugriff auf die erhaltenen Umgebungs-Variablen, meist in Form von Arrays.

Quick & Dirty:
Wenn die Zeit knapp ist, oder wenn man sich ohne Erfolg in den Tiefen des Betriebssystems verirrt hat, dann kann man einer Variablen auch direkt einen Wert zuweisen wie
$myproxy = '192.168.0.1:8080';
Das funktioniert, hat jedoch Nachteile: Das Programm ist nicht auf andere Server portabel. Ein Murphy-Gesetz (en) besagt, dass Router-Adresse und Port genau dann geändert werden, wenn man vergessen hat, welche unsauberen Programme in diesem Fall anzupassen sind.

Details zu Umgebungs-Variablen in Perl, PHP und zur Konfiguration von PHP.

Beispiel → Perl:
$myproxy = '';
if(exists($ENV{'HTTP_PROXY'})) {
$myproxy = $ENV{'HTTP_PROXY'};
}

Beispiel → PHP:
$myproxy = '';
if(isset($_ENV['HTTP_PROXY'])) {
$myproxy = $_ENV['HTTP_PROXY'];
}
Das → Globale Array $_ENV wird nur dann besetzt, wenn in der → PHP-Konfigurations-Variablen variables_order ein 'E' eingetragen ist, z.B.:
variables_order = "EGPC"
Wenn $_ENV nicht besetzt ist, kann man normalerweise das Element $_SERVER['HTTP_PROXY'] verwenden.
Beachten sie außerdem, dass Linux-Server meist zwischen PHP als Apache-Modul und PHP als CGI-Programm unterscheiden: Jede der beiden Anwendungen wird mit einer eigenen Datei php.ini konfiguriert !


Letzte Änderung dieser Seite: 2011-11-29 23:02:16