HTTP-Request

Anforderung von Daten mit dem HTTP-Protokoll

Das HTTP-Protokoll ist der bekannteste Offene Standard im Internet. Das Protokoll legt die Regeln fest, nach denen Daten (Webseiten) im Internet transportiert werden. Der HTTP-Request ist jener Teil des HTTP-Protokolls, mit dem Daten angefordert werden. Der Request ist ein kurzer Text-Block, der normalerweise vom Browser (Client) an den zuständigen Webserver gesendet wird.
Internet Protokolle, Dienste und Services - HTTP
HTTP Grundlagen und Übersicht
Live Anzeige des HTTP-Requests für diese Webseite
Analyse Lesen des HTTP-Headers (mit PHP)
Syntax 'Grammatik' des HTTP-Request
Port Aufteilung von Daten-Paketen an verschiedene Prozesse
Router Daten-Schnittstelle zwischen LAN und Internet
Synthese Programmierter Aufbau des HTTP-Request
Verwandte Themen:
HTTP-Response Details zum HTTP-Response-Header
HTTP Status Code ZahlenCode zum Erfolg einer Browser-Anfrage
HTML Die Programmiersprache für Webseiten (ausgewählte Themen)

Live HTTP-Anforderung (Request) für diese Webseite

Wenn mit → TCP/IP eine Verbindung aufgebaut wurde, dann sendet ihr Browser eine Anfrage an den Webserver. Die Anfrage (Auftrag, Request) ist ein nach HTTP-Regeln aufgebauter einfacher Text (text/plain). Die Verwendung von einfachem Text macht das HTTP-Protokoll besonders einfach, andererseits bereitet auch das unbefugte Abhören der Daten-Pakete keine Schwierigkeit.
Die benötigte PHP-Funktion   apache2handler()   ist am Webserver nicht verfügbar.
Simulation jenes HTTP-Request's, mit dem ihr Browser diese Webseite angefordert hat:
GET http://www.topsoft.at/pstrainer/system/netzwerk/internet/http_request.php HTTP/1.1
User-Agent: CCBot/1.0 (+http://www.commoncrawl.org/bot.html)
Host: www.topsoft.at
Accept: text/xml, text/html, image/png, image/jpeg, image/gif
Accept-Language: de
Referer: http://www.topsoft.at/pstrainer/system/netzwerk/internet/internet.html
Connection: Keep-Alive
Am anderen Ende des mit → TCP/IP aufgebauten Daten-Kanals "lauscht" ein Webserver (auf → Port 80) auf Aufträge. Ein Webserver hat als typisches Server-Programm keine Oberfläche, d.h. der Server arbeitet ohne jedes Bedienungs-Fenster im Hintergrund.

Telnet

Jedes gängige Betriebssystem bietet das → Konsolen-Programm telnet
Obwohl mittlerweile veraltet, kann man damit manuell (!) einen HTTP-Request an einen beliebigen Webserver (im eigenen LAN oder im Internet) senden.
Diese Methode eignet sich gut zur Fehler-Suche und für Lern-Zwecke.

Spionage

Im Internet sind zahlreiche Programme (Packet-Sniffer, Paket-Monitor, WireShark, ...) verfügbar, mit denen man alle (!) im lokalen Netzwerk transportierten IP Daten-Pakete analysieren kann.
Diese Programme erfordern meist einige technische Kenntnisse, sind jedoch zur Fehler-Suche und für Lern-Zwecke gut geeignet.

Programmierung

Moderne (Server)-Programmiersprachen wie → Java, → Perl oder → PHP bieten sowohl die Möglichkeit, einlangende HTTP Requests zu analysieren als auch beliebige HTTP-Requests an entfernte Webserver zu senden.

Die ↓ Analyse wird nur selten verwendet, da alle wesentlichen Daten auch in den → Umgebungs-Variablen des Server-Programms verfügbar sind. Man kann die Angaben dazu verwenden, um dynamische Webseiten (oder andere Produkte, z.B. Grafik) nach den Wünschen und Fähigkeiten des Browsers zu gestalten.
Umgebungs-Daten von Perl, PHP, ...

Die ↓ Synthese kann man dazu verwenden, um Webseiten oder andere Daten von entfernten Webservern anzufordern, und sich dabei als beliebiger User-Agent zu tarnen. In manchen Fällen kann man damit Filter überwinden (die auf der Analyse des HTTP Request-Headers beruhen).

Analyse des HTTP-Headers

apache2handler

Die Programmiersprache PHP ermöglicht die Analyse der HTTP-Daten auf Protokoll-Ebene.
Der HTTP Request Header enthält in einem kurzen Text-Block die Daten-Anforderung und einige Daten zur Identifikation des Clients.
Der Client ist in den meisten Fällen ein Browser, seltener ein automatisch arbeitendes Programm (Spider, Bot, Crawler, Web-Analyse für Suchmaschinen) oder andere Software - z.B. spezielle PHP-Programme.

apache2handler

Das → PHP-Modul apache2handler enthält einige praktische HTTP-Funktionen, es müssen jedoch einige Voraussetzungen erfüllt sein:
Das Modul ist nur zusammen mit einem → Apache Webserver verfügbar.
PHP muss als Apache-Modul (typisch auf Linux) installiert sein. Installation als CGI-Programm (typisch auf Windows und bei Web-Providern) genügt nicht.
Das Modul ist erst ab PHP-Version 4.3 verfügbar.
Manche Web-Provider verwenden spezielle PHP-Versionen ohne dieses Modul, oder seine Verwendung durch Standard-Kunden ist unterbunden.

Das Modul enthält u.a. die Funktion apache_request_headers zur Analyse der HTTP-Anforderung.

Details zu PHP, PHP-Modulen, PHP-Modul apache2handler
PHP-Homepage - Apache-Funktionen (de, en)
Live PHP Version:
phpversion() = 5.3.3-7+squeeze9
Live PHP-API:
php_sapi_name() = cgi-fcgi
Live PHP → Modul- und Funktions-Test:
PHP-Modul apache2handler ist nicht verfügbar !
Hinweise zur Programmierung der gezeigten Funktionen (rechts)
Alle PHP Programmteile können an beliebiger Stelle in Webseiten enthalten sein, müssen jedoch in spezielle Auszeichnungs-Elemente (tags) gestellt werden, z.B.
<?php
Print 'Hier ist PHP';
?>

Arrays, Module, Funktionen in PHP
PHP-Version:
print 'PHP-Version = '.phpversion();
PHP-API (Application Programming Interface)
print 'PHP-API = '.php_sapi_name();
Modul apache2handler
$a2h = 0;
if(extension_loaded('apache2handler')) {$a2h=1;}
Funktion apache_request_headers
$arh = 0;
$fa = get_extension_funcs('apache2handler');
if(in_array('apache_request_headers',$fa)) {$arh=1;}

apache_request_headers

Anwendung der Funktion apache_request_headers
Damit wird der HTTP-Request genau des aufgerufenen Script-Programms analysiert. Die Funktion muss sich innerhalb jener dynamischen Webseite befinden, die (vom Browser) aufgerufen wurde.
Das Ergebnis wird als assoziatives → Array zurückgegeben, d.h. sauber getrennt in Name und Wert der Variablen.
Diese Funktion liefert leider nicht (immer) alle Header-Variablen.
In der Live-Ausgabe (oben) des Beispiels finden sie jenen HTTP-Header, mit dem ihr Browser diese dynamische Webseite vom Webserver angefordert hat.

Analyse jenes HTTP-Requests, mit dem das PHP Script-Programm aufgerufen wurde:
$arh = apache_request_headers ();
foreach ($arh as $h=>$v) {
print "$h: $v<br />\n";
}

Umgebungs-Daten

Die meisten der im HTTP-Request enthaltenen Daten kann man auch aus den immer verfügbaren → Globalen Arrays der → Umgebungs-Daten entnehmen, andere (z.B. → IP-Adresse und → Port) sind nur dort zu finden.
Davon ausgehend lassen sich weitere Daten ermitteln, z.B.
Browser-Fähigkeiten mit PHP-Funktion get_browser()
User-Daten: Der Internet-Dienst whois liefert die offiziell registrierten Daten der/des AnwenderIn oder des Providers, weitere Dienste liefern Staat, Standort, geografische Koordinaten, Zeitzone u.a. Daten (PHP-(PECL)-Modul GeoIP).
Ausgewählte Live-PHP → Umgebungs-Daten - Ergänzung und Ersatz der Daten aus dem HTTP Request
(In jeder PHP-Version verfügbar)
$_SERVER["HTTP_ACCEPT"] = text/html,application/xhtml+xml,text/xml;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
$_SERVER["HTTP_ACCEPT_CHARSET"] = ISO-8859-1,utf-8;q=0.7,*;q=0.7
$_SERVER["HTTP_ACCEPT_ENCODING"] = gzip
$_SERVER["HTTP_ACCEPT_LANGUAGE"] = en-us,en;q=0.5
$_SERVER["HTTP_CONNECTION"] = close
$_SERVER["HTTP_KEEP_ALIVE"] = nicht definiert
$_SERVER["HTTP_REFERER"] = nicht definiert
$_SERVER["HTTP_USER_AGENT"] = CCBot/1.0 (+http://www.commoncrawl.org/bot.html)
$_SERVER["QUERY_STRING"] =
$_SERVER["REMOTE_ADDR"] = 38.107.179.214
$_SERVER["REMOTE_PORT"] = 48726
$_SERVER["REQUEST_METHOD"] = GET
$_SERVER["REQUEST_TIME"] = 1337728460 (UNIX TimeStamp) = 2012-05-23 01:14:20
$_SERVER["REQUEST_URI"] = /pstrainer/system/netzwerk/internet/http_request.php

Syntax des HTTP-Request

Eine HTTP-Anforderung muss nach HTTP-Standard (RFC 2616 für HTTP 1.1) formuliert sein. Der Text besteht aus einem "GET"-Befehl und optionalen Variablen.
Es gibt auch andere HTTP-Requests, diese werden jedoch wesentlich seltener verwendet:
CONNECT, DELETE, (GET), HEAD, OPTIONS, POST, PUT, TRACE

GET-Befehl

Eine Text-Zeile, beginnend mit dem Wort GET, danach der Pfad zur angeforderten Datei, danach die HTTP-Version.
Bei manueller Eingabe (Telnet, cURL) genügt das Schlüsselwort GET, gefolgt vom Datei-Pfad.

Beispiel:
GET http://pstrainer.topsoft.at/ HTTP/1.1

HTTP-Request-Variable

Nach dem GET-Befehl folgen optional Variable, jeweils in einer eigenen Zeile in der Form name: wert
Anzahl und Reihenfolge der Header-Variablen werden je nach Browser und Version (leider) etwas unterschiedlich formuliert.
Es folgt die Vorstellung einiger willkürlich ausgewählter HTTP-Request Variablen:

Beispiel (jede Variable in einer eigenen Zeile, z.B.)
Accept-Language: de
Accept
Diese Variable signalisiert dem Webserver, welche Daten-Typen (bevorzugt) verarbeitet werden können. Die Daten sind → MIME-Definitionen, durch Beistrich getrennt.

Trotzdem wird kein vernünftiger Mensch einem M$IE Browser etwa eine M$Word Textverarbeitungs--Datei senden.
Accept-Charset
Jeder gängige Browser 'versteht' mindestens den → ASCII und den → Unicode Zeichensatz utf-8

Die meisten Browser (vor allem deutschsprachige Versionen) verstehen auch → Zeichensätze der → ISO-8859-Familie, z.B. iso-8859-1
Accept-Encoding
Man kann auch komprimierte Archive der angegebenen Typen verwenden.

Das ist für große Dateien sehr empfehlenswert, denn das Auspacken der Archive durch den Client-PC benötigt viel weniger Zeit als der Daten-Transport - vor allem bei langsamen Verbindungen.
Connection
Mit dem Wert "Keep Alive" ersucht der Browser, die Verbindung nach der Übersendung aller Daten nicht zu trennen.

Das ist sinnvoll, wenn sofort nach einer Webseite mehrere darin enthaltene Objekte (z.B. Bilder) vom gleichen Webserver angefordert werden.
Fast alle Webserver ignorieren jedoch diesen Wunsch und trennen die Verbindung sofort nach Ausführung des Auftrags.
Host
Domain-Name bzw. IP-Adresse des Webservers

Normalerweise der Anfangs-Teil jenes Pfades, der bereits im GET-Befehl (1. Zeile) angegeben wurde.
Keep-Alive
Eine Ergänzung der Variablen Connection.

Der Wert gibt an, wieviele Sekunden nach dem Übersenden aller angeforderten Daten die Verbindung offen bleiben soll.
Referer
Pfad zur verweisenden Webseite (wo sich der Link zur aktuellen Seite befand). Sollte eigentlich Referrer heißen, ist jedoch in dieser Form eingebürgert.

Der Wert dieser Variablen wird von vielen Webservern für eine Statistik ausgewertet (Tracker-Programme).
User-Agent
Type und Version des Clients (Browser).
Meist sind auch Informationen zum Betriebssystem enthalten.

Die Daten können für die Statistik verwendet werden, oder für Browser-spezifische Verzweigungen.

Port

An jedem PC (sowohl Client als auch Server) treffen zahlreiche (→ IP)-Daten-Pakete ein. Gleichzeitig warten ("lauschen", listen) mehrere Prozesse auf Daten. Das → Port-Konzept steuert die Daten-Pakete innerhalb eines PC (d.h. bei gleicher → IP-Adresse) zum richtigen Prozess. An jeden Prozess, welcher plant, Daten anzunehmen, wird vom Betriebssystem eine eigene Port-Nummer (0..65535) vergeben.

Fixe Port-Nummern

Prozesse wie → Webserver, die routinemäßig lange Zeit hindurch auf Daten (HTTP-Requests = Aufträge) lauschen, erhalten fixe Port-Nummern. Die IANA verwaltet diese Nummern weltweit.
Web-Server lauschen normalerweise auf Port 80, in seltenen Fällen wird Port 8000 oder 8080 verwendet.

Wenn Daten an einen Standard-Prozess gesendet werden, dann muss die Port-Nummer nicht eigens angegeben werden. Ein Client (Browser) kann beispielsweise diese Webseite anfordern (beide Anforderungen sind äquivalent).
Wenn ein Webserver auf eine andere Port-Nummer konfiguriert ist, dann muss man sie in der URL-Adresse angeben:
http://www.gibts.nicht:8080

Wikipedia: Port, IANA - Ports

Variable Port-Nummern

Alle anderen Prozesse (z.B. Browser-Programme) erhalten vom Betriebssystem beliebige Port-Nummern, die gerade frei sind.
Beispiel:
Ein Browser sendet einen HTTP-Request mit Port-Nr. 1234
Die Daten der Webseite treffen mit Ziel an den gleichen Port ein.
In der Webseite findet der Browser 3 Bilder.
Er fordert diese mit weiteren HTTP-Requests unter den Port-Nummern 1235, 1236, 1237 an.
Einige Zeit nach Eintreffen aller Daten (oder nach Timeout) können die gleichen Port-Nummern für andere Prozesse verwendet werden.
Die aktuellen IP-Adressen und Port-Nummern von Client und Server kann man aus den Umgebungs-Daten entnehmen.
Wenn sie die Live-Daten (rechts) lesen, wurde die Verbindung allerdings schon längst beendet.
Live-Daten dieser Verbindung zwischen ihrem Browser und dem Webserver:
$_SERVER["REMOTE_ADDR"] = 38.107.179.214
$_SERVER["REMOTE_PORT"] = 48726
$_SERVER["SERVER_ADDR"] = 192.168.255.11
$_SERVER["SERVER_PORT"] = 80

Router / Proxy-Server

Dieses Kapitel trifft dann zu, wenn ein PC nicht direkt mit dem Internet verbunden ist, sondern über einen → Router bzw. → Proxy-Server.
Private Heim-Netzwerke verwenden dazu meistens fertig konfigurierte 'BlackBox' Geräte, meist mit weiteren integrierten Funktionen (Hub, Access Point, DHCP-Server, Print-Server, FileServer = gemeinsame Festplatte, usw...).
Professionelle Netzwerke verwenden eine Software-Lösung auf einem Standard-PC, z.B. Squid, meist kombiniert mit anderen Server-Funktionen (Firewall, Viren-Scanner, ...)
Jeder Router enthält (mindestens) 2 Netzwerk-Interface (meistens → Ethernet) und damit 2 verschiedene → IP-Adressen:
Ein Interface verbindet mit dem lokalen Netzwerk (LAN), ein anderes mit dem Internet (Provider).
Die LAN-Adresse wird fix eingestellt (z.B. auf 192.168.0.1), da man sie allen PC und Browser-Programmen bekannt geben muss.

Port

Der Router lauscht an einem bestimmten fix eingestellten Port (z.B. 8080) auf jene Daten aus dem lokalen Netzwerk (LAN), die ins Internet geleitet werden sollen.
IP-Adresse und Port-Nummer des Routers müssen jeder betroffenen Software auf jedem einzelnen PC im LAN bekannt sein.
Wenn das LAN nur wenige Geräte umfasst, dann werden die Router/Proxy-Daten an jedem PC / jedem Browser einzeln eingestellt.
In größeren Netzwerken erfolgt die automatische Einstellung meist mit einem → Autoproxy-Script

Jeder Router führt eine Tabelle aller durchlaufenden Anfragen.
Von jeder ausgehenden Anfrage (z.B. HTTP-Request) wird IP-Adresse und Port-Nummer der Herkunft eingetragen.
Das Daten-Paket wird mit einer neuen Port-Nummer des Routers versehen und mit dessen Internet-Adresse weitergeleitet.
Wenn Daten aus dem Internet an den Router eingehen, dann wird die Port-Nummer (des Routers) in der Tabelle aufgesucht.
Das Daten-Paket wird mit der dort aufgefundenen IP-Adresse und Port-Nummer versehen und ins LAN weitergeleitet.
So finden die Daten ihren Weg zum Ausgangspunkt (Browser).

Synthese eines HTTP-Request

Alle modernen Programmiersprachen können eine (Netzwerk)-Verbindung zwischen 2 Endpunkten (→ Sockets) aufbauen und darüber Daten in beide Richtungen austauschen.
Die entsprechenden Funktionen finden sie unter dem Stichwort socket
Da der HTTP-Request aus reinem Text (text/plain) besteht, ist es vergleichsweise einfach, mit einem eigenen Programm beliebige Texte zu formulieren und an einen entfernten Server zu senden.
Der Text des HTTP-Request wird in der Variablen $out zusammengestellt. Um einen bestimmten Agent (Browser) zu simulieren, untersuchen sie vorher genau einen Request dieses Browsers.

Mit Funktion fsockopen (PHP-Modul standard) wird der HTTP-Request gesendet (in diesem Fall über den Router 192.168.0.1:8080 )
Die dabei erhaltene Variable $fp wird als Handle für alle Zugriffe auf diesen Kommunikations-Kanal verwendet.

Mit Funktion fwrite wird der HTTP-Request an den entfernten Server gesendet.

Danach wartet das Programm auf eintreffende Daten-Pakete. Die Daten werden in der while-Schleife zeilenweise mit Funktion fgets empfangen und verarbeitet.

Als Muster für eine Verarbeitung wird jede Zeile mit Funktion htmlentities → HTML-codiert und danach ausgegeben ( d.h. auf einer damit erstellten Webseite angezeigt).
PHP-Beispiel für die Synthese eines HTTP-Request und dem anschließenden Empfang der angeforderten Daten mit PHP:
// HTTP-Request zusammenstellen
$out = 'GET http://www.ziel.de/index.html';
$out.=" HTTP/1.1\r\n";
$out.="Accept-Language: de\r\n";
// ...weitere Variable
$out.="Host: www.ziel.de\r\n";
$out.="\r\n";
$proxy = '192.168.0.1';
$proxyport = '8080';
$timeout = 15;
// Kanal öffnen
$fp = fsockopen($proxy,$proxyport,$errnr,$errmsg,$timeout);
if ($fp) {
// Request senden
fwrite($fp,$out);
}
// Empfang
if($fp) {
stream_set_timeout($fp,$timeout);
while (!feof($fp)) {
$line = fgets($fp,1024);
// Verarbeitung
$hline = htmlentities($line);
print "$hline<br />\n";
}
fclose($fp);
}
Verarbeitung:
Es ergibt wenig Sinn, eine angeforderte Webseite so wie im Beispiel mit einem eigenen Programm auszugeben - Jeder Browser kann das besser und schneller.

Das Beispiel soll lediglich den technischen Ablauf demonstrieren. Es bleibt den EntwicklerInnen überlassen, was man mit den empfangenen Daten macht.
In den meisten Fällen werden die Daten analysiert und bestimmte Werte daraus entnommen. Für diesen Zweck sind → Reguläre Ausdrücke am besten geeignet.

Letzte Änderung dieser Seite: 2011-11-29 23:02:13
XHTML CSS