HTTP

HTTP ist eines der am häufigst gebrauchten Protokolle im Internet und funktioniert nach einem einfachen Prinzip:

  • Clients (Browser) formulieren ihren Request und schicken Ihn an den Server
  • Webserver (z. B. Apache, IIS u. a.) geben eine Statusmeldung zurück, formulieren ihre Response (die angeforderte Ressource, z. B. eine HTML-Datei) und schicken alles zusammen an den Client

Struktur

HTTP ist prinzipiell zustandslos. Das heißt, es werden keine Informationen über den Zustand (z. B. vorhergehende Requests) einer Sitzung zwischen Client und Server versendet oder gespeichert.
Über Query-Strings, Cookies oder Sessions in den Header-Informationen, besteht allerdings die Möglichkeit, auf vergangene Requests Bezug zu nehmen.
Der Aufbau eines HTTP-Paketes teilt sich in Header, Body (und seltener Trailer):

Struktur des HTTP-Protokolls

Dabei unterteilt sich der Header in die so genannte Request- oder Response-Line und den MIME-Header.
Im Body steht dann der eigentliche Inhalt, was z. B. die Antwort des Servers, Formulardaten oder auch gar nichts sein kann (also ein leerer Body).
In der Praxis sieht der HTTP-Header eines Client-Requests etwa so aus:

GET /simple/index.php?page=home HTTP/1.1
Host: php.nobs-nobody.de
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml
Accept-Language: de-de, de, en-us, en
Accept-Encoding: gzip, deflate
Connection: keep-alive

Die erste Zeile ist die Request-Line und besteht aus drei Teilen:

  • Request-Methode, man könnte sagen der Anfragetyp: GET
  • Request-Uri, die Ressource, die angefordert wird, also: /simple/index.php?page=home auf dem Server php.nobs-nobody.de
  • Request-Version, die Version des HTTP-Protokolls, hier: HTTP/1.1

Versionen

Beim HTTP werden zwei Versionen unterschieden – 1.0 und 1.1 – und eine Entwicklergruppe der IETF arbeitet an einer neuen Version 2.0.
Während Version 1.0 des HTTP bei der Kommunikation für jeden einzelnen Request eine neue (TCP-)Verbindung benötigt, die initialisiert werden muss und bei Abschluss der Transaktion vom Server wieder geschlossen wird, werden seit der Version 1.1 die so genannten ‚persistent connections‘ unterstützt.
Damit kann jeder Client, der das Headerfeld ‚Connection: Keep-Alive‘ setzt, innerhalb einer Verbindung mehrere Requests versenden, was z. B. dann notwendig ist, wenn in HTML-Dateien auf CSS-Dateien verwiesen wird bzw. Bilder eingebunden werden.
Eine HTML-Datei, die link-Tags auf CSS-Dateien und ein Bild beinhaltet, benötigt 4 Requests für die vollständige Darstellung der Seite im Browser (1x HTML, 2x CSS, 1x Bild – siehe Grafik).

Requests für php.nobs-nobody.de

Über das so genannte Pipelining ist es – wie man sieht – bei HTTP/1.1 sogar möglich, dass mehrere Requests und Responses zwischen Client und Server parallel innerhalb einer Verbindung ausgetauscht werden, dass also z. B. mehrere CSS-Dateien, die im HTML angegeben sind, parallel geladen werden.

URI

Der URI (uniform resource identifier) ist die Web-Adresse, die z. B. in der Adressleiste des Browsers eingegeben wird, also:

http://php.nobs-nobody.de/simple/index.php?page=home

Der Aufbau folgt dabei einem einfachen Prinzip:

Protokoll://server/pfad/datei?query-string

Für Protokoll steht hier ‚http‘.
Der Server ist der, der im Request-Header als Host angegeben ist, also ‚php.nobs-nobody.de‘.
Der Pfad gibt den Speicherort auf dem Server an, hier der Ordner ‚/simple/‘ und die Datei ‚index.php‘.
Der Query-String besteht aus Schlüssel-Werte-Paaren der Form ’schlüssel=wert‘ und wird mit dem Fragezeichen eingeleitet. Mehrere solcher Paare kann man mit dem & verknüpfen, z. B.:
‚?key1=wert1&key2=wert2& …‘.
Beachtet aber dass URI’s im Allgemeinen nicht länger als 255 Zeichen sein sollten.

Mitunter werden einzelne Bestandteile auch weggelassen, wenn z. B. die Datei im Wurzelverzeichnis liegt, gibt es keinen Pfad (Ordner) und auch der Query-String ist für einen GET-Request (siehe unten) rein optional.
Übrigens wenn im URI keine Datei angegeben ist, entscheidet der Server anhand seiner Konfiguration, was er macht.
Ist ein so genannter ‚directory index‘ definiert, wird die Standarddatei (z. B. index.html oder index.php) übertragen, die dort angegeben ist. Ist der ‚directory index‘ nicht definiert, kann der Server ein ‚directory listing‘ (Übersicht über den Verzeichnisinhalt) zurückgeben, allerdings nur, wenn dieses auch aktiviert ist. Ansonsten gibt der Server eine 404 – Fehlermeldung (‚Not found‘) zurück.

Request

Bei den Request-Methoden unterscheidet man vor allem GET und POST.
Über GET wird eine Ressource (z. B. eine Datei) unter Angabe einer Webadresse (URI) vom Server angefordert. Als Argument kann dabei auch der Query-String zum Server übertragen werden.

POST schickt nahezu unbegrenzte Mengen an Daten zur weiteren Verarbeitung zum Server, diese werden als Inhalt der Nachricht übertragen und können aus Schlüssel-Werte-Paaren bestehen, die aus HTML-Formularen stammen. POST-Daten werden im Allgemeinen nicht von Caches zwischengespeichert. Zusätzlich können bei dieser Art der Übermittlung auch Daten wie in der GET-Methode an den URI gehängt werden.

Eine Liste aller Request-Methoden gibt’s hier: HTTP-Request-Methoden.

Header

Im MIME-Header des HTTP sind spezielle Request-Features eingetragen, die dem Server Genaueres über den Request, die angeforderte Ressource und/oder den Client mitteilen. Man hat als Web-Entwickler mitunter erheblichen Einfluss auf diese Felder, abhängig davon, wie die zu entwickelnde Web-Anwendung arbeiten soll.
Das heißt auch, dass die Anzahl der Felder variabel ist und auch wenn alle Felder einen definierten Namen haben müssen, so kann man über die Angabe einzelner Felder selbst bestimmen. In unserem Beispiel bedeuten die Felder Folgendes:

  • Host: der angefragte Server
  • User-Agent: Informationen über den Client, z. B. welcher Browser
  • Accept: Dateitypen, die der Client als Antwort akzeptiert, hier könnte z. B. auch ‚text/css‘ für styles oder ‚image/*‘ für Bilder stehen
  • Accept-Language: die erwartete Sprache des Clients
  • Accept-Encoding: die erwartete Codierung, heutige Clients fordern immer öfter auch komprimierte Dateien (gzip, deflate) an, um Bandbreite zu sparen
  • Connection: das keep-alive bedeutet, dass der Client die Verbindung nach der Antwort des Servers aufrechterhalten will, was in der Version HTTP/1.1 daran liegt, dass mit jedem neuen Dateityp, der in eine Webseite integriert ist, ein neuer Request des Clients über diese Verbindung verschickt wird

Eine Liste der Felder im HTTP-Protokollheader findet Ihr hier HTTP-Header-Felder.

Response

Erreicht der obige Request den Server, generiert dieser seine Antwort, die wie folgt aussehen könnte:

HTTP/1.1 200 OK
Date: Mon, 08 Jul 2013 08:34:30 GMT
Server: Apache/2.2.24 (Unix)
X-Powered-By: PHP/5.2.17
Cache-Control: max-age=600, private, must-revalidate
Expires: Wed, 07 Aug 2013 08:34:30 GMT
Keep-Alive: timeout=3, max=100
Content-Type: text/html
Content-Length: 7522
Proxy-Connection: Keep-Alive

Auch hier besteht die erste Zeile (die Response-Line) aus drei Teilen:

  • Request-Version, die Version des HTTP, hier: HTTP/1.1
  • Status-Code, der Status der angeforderten Ressource: 200 bedeutet Anfrage erfolgreich verarbeitet, Ergebnis wird als Antwort gesendet
  • Response-Phrase, die Antwort-Meldung des Servers, eine Beschreibung des Status-Codes in englischsprachigem Klartext, hier: OK

Die Status-Codes unterteilen sich dabei prinzipiell in fünf (bzw. sechs) verschiedene Klassen (abhängig von der ersten Stelle der dreistelligen Zahl):

  • 1xx: Information
  • 2xx: Verarbeitung erfolgreich
  • 3xx: HTTP-Umleitung
  • 4xx: Client-Fehler
  • 5xx: Server-Fehler
  • 9xx: Proprietäre (heißt herstellereigene) Codes, Netzwerkfehler

Eine Liste der Status-Codes gibt’s hier: HTTP Status Codes.

Findet der Server die angeforderte Datei nicht (404 – Not found) oder hat der Client keine Berechtigung, diese Datei zu empfangen (403 – Access denied), fällt auch die Server-Antwort unterschiedlich aus. Bei einem Status-Code von 200 (OK), wie in unserem Beispiel, wird die angeforderte Datei in den Payload gepackt und das Paket versendet, wobei der Server in den MIME-Header dann noch Informationen zu dieser Antwort schreibt. In unserem Beispiel sind das die Folgenden:

  • Date, das Datum des Servers in festgelegtem Format (RFC 1123)
  • Server, die Server-Plattform, die man aus Sicherheitsgründen unterdrücken sollte: ein Apache-Server der Version 2.2.24
  • X-Powered-By, die serverseitige Skript-Engine, auch diese sollte man aus Sicherheitsgründen unterdrücken, hier: PHP Version 5.2.17
  • Cache-Control, Informationen, ob die Datei von einem Proxy zwischengespeichert werden kann, die Angaben sind für schnelle Ladezeiten wichtig
  • Expires, maximales Alter der angeforderten Datei
  • die Dauer des Keep-Alive, also wie schnell der Client seine weiteren Requests senden muss
  • Angaben zum Inhalt: HTML-Datei (‚text/html‘) 7522 Byte groß
  • und die Angabe, dass eine persistente Verbindung (nur HTTP/1.1) gehalten wird

Eine wichtige Rolle bei der Antwort des Servers spielen vor Allem drei Dinge: der Client-Request-Header, die Server-Konfiguration (z. B. httpd.conf, .htaccess) und die HTML-/PHP-Konfiguration und Typen der Dateien.

Der Client gibt im Request-Header schon vor, was er haben will. Aber der Server prüft erst, ob er die angeforderten Ressourcen auch auf die Art verarbeiten kann, ehe er sein Paket schnürt.
Schickt der Client in seinem Request z. B. ein ‚Accept-Encoding: gzip, deflate‘, schaut ein Apache-Server auf der einen Seite in seine Konfiguration (z. B. eine .htaccess-Datei im Ordner der angeforderten Ressource oder die Informationen in der Konfigurationsdatei des Servers),ob er die gzip-Kompression mit deflate auch unterstützt (heute aber eigentlich alle). Auf der anderen Seite durchsucht er das angeforderte Verzeichnis, ob eine entsprechend komprimierte Datei auch existiert, die er versenden kann.
Geht dabei etwas schief, versucht der Server eine unkomprimierte Version der Datei zu versenden oder generiert eine Fehlerantwort. Ansonsten erhält der Client die entsprechend komprimierte Datei.

Aber auch die PHP- oder HTML-Dateien sind wichtig, da dort z. B. in den meta-Tags bzw. mit der Funktion ‚header();‘ im Falle von PHP, weitere Konfigurationen des MIME-Headers festgelegt sein könnten.
Alles in Allem ist die Antwort des Servers von vielen Faktoren abhängig, auf die der Web-Entwickler einen relativ großen Einfluss hat.

Verständlicherweise kann man als Webentwickler damit aber nicht nur die Ladezeit seiner Webseite erheblich beeinflussen, was die Übertragung des Markups angeht (die HTML-Datei). Es ist insbesondere möglich, auf der einen Seite die Anzahl der Request zu reduzieren, indem man die Anzahl der zu übertragenden Dateien minimiert.
Auf der anderen Seite spielen aber sowohl die schon angesprochene Komprimierung als auch das Zwischenspeichern auf Proxies eine wichtige Rolle bei der Minimierung des Datenverkehrs und damit der Ladezeiten Eurer Webseiten.

Mehr dazu auf der SEO-Seite.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.