Im letzten Jahr haben wir in der Geburtstagswoche die vorläufige Unterstützung für QUIC und HTTP/3 angekündigt (oder, wie es damals hieß, „HTTP over QUIC“), den neue Standard für das Web mit schnelleren, zuverlässigeren und sichereren Verbindungen zu Web-Endpunkten wie Websites und APIs. Außerdem haben wir unsere Kunden in eine Warteliste zum Testen von QUIC und HTTP/3 bei Verfügbarkeit aufgenommen.

Seitdem arbeiten wir im Rahmen der Internet Engineering Task Force mit Kollegen aus der Branche, darunter auch Google Chrome und Mozilla Firefox, an den Dokumenten für die HTTP/3- und QUIC-Standards. Das ist ein iterativer Prozess. Gleichzeitig mit der Ausarbeitung dieser Standards haben wir auch ihre Unterstützung auf unserem Netzwerk verbessert.

Wir freuen uns, Ihnen nun mitteilen zu können, dass das Cloudflare Edge-Netzwerk QUIC und HTTP/3 unterstützt. Und ganz besonders freuen wir uns, dass dies gleichzeitig auch für Google Chrome und Mozilla Firefox angekündigt wurde. Diese beiden führenden Browser-Anbieter sind Partner bei unserem Bemühen, das Web für alle schneller und zuverlässiger zu machen.

Ryan Hamilton, Staff Software Engineer bei Google, erklärt dazu: „Mit HTTP/3 wird das Web besser für alle. Die Chrome- und Cloudflare-Teams haben HTTP/3 und QUIC in enger Zusammenarbeit vom Stadium eines neu aufkommenden Standards zum Stadium einer weithin akzeptierten Technologie geführt, die das Web verbessert. Solche starken Partnerschaften zwischen Branchenführern machen Innovationen bei Internetstandards möglich, und wir freuen uns schon auf die Fortsetzung dieser Zusammenarbeit.“

Was bedeutet das nun für Sie als Cloudflare-Kunden, der seine Webpräsenz mit unseren Diensten und unserem Edge-Netzwerk schneller und sicherer machen möchte? Sobald die HTTP/3-Unterstützung für Ihre Domain im Cloudflare-Dashboard aktiviert ist, können Ihre Kunden über HTTP/3 mit Ihren Websites und APIs interagieren. Wir laden schon seit längerem Kunden auf unserer HTTP/3-Warteliste ein, die Funktion einzuschalten (achten Sie also auf eine E-Mail von uns), und in den kommenden Wochen werden wir die Funktion für alle verfügbar machen.

Was bedeutet diese Nachricht für Sie, wenn Sie als Internetnutzer mit einem Browser und anderen Clients Websites und APIs aufrufen? Ab heute können Sie mit Chrome Canary über HTTP/3 mit Cloudflare und anderen Servern interagieren. Für diejenigen, die nach einem Befehlszeilenclient suchen: curl bietet ebenfalls Unterstützung für HTTP/3. Eine Anleitung für Chrome und curl mit HTTP/3 finden Sie weiter unten in diesem Beitrag.

Die Henne und das Ei

Innovationen bei Internetstandards waren schon immer schwierig, denn es ist wie mit der Henne und dem Ei: Was kommt zuerst, die Serverunterstützung (Cloudflare oder andere große Quellen von Antwortdaten) oder die Client-Unterstützung (Browser, Betriebssysteme usw.)? Ein neues Kommunikationsprotokoll muss von beiden Seiten einer Verbindung unterstützt werden, damit es zu etwas nutze ist.

Cloudflare hat schon immer die Standards im Web vorangetrieben, von HTTP/2 (die HTTP-Version vor HTTP/3) über TLS 1.3 bis hin zu Dingen wie verschlüsselter SNI. Durch Partnerschaften mit gleichgesinnten Organisationen, die wie wir den Wunsch haben, das Internet besser zu machen, haben wir Standards vorangebracht. Genauso ist es bei unseren Bemühungen, HTTP/3 in den Mainstream zu bringen.

Während des gesamten Entwicklungsprozesses der HTTP/3-Standards haben wir eng mit Partnern aus der Branche zusammengearbeitet, um HTTP/3-Client-Unterstützung zu entwickeln und zu validieren, die mit unserer Edge-Unterstützung kompatibel ist. Wir freuen uns, dass Google Chrome und curl uns dabei begleiten. Beide können nun für Anfragen über HTTP/3 an die Cloudflare-Edge verwendet werden. Bei Mozilla Firefox soll diese Unterstützung demnächst im Rahmen einer Nightly-Version ebenfalls ausgeliefert werden.

Deshalb ist heute ein guter Tag für Internetnutzer. Die Einführung von HTTP/3 auf breiter Front bedeutet ein schnelleres Web für alle, und die heutige Unterstützung ist ein großer Schritt in diese Richtung.

Aber vor allem ist heute ein guter Tag für das Internet: Chrome, curl, Cloudflare und bald auch Mozilla führen schnell hintereinander die Unterstützung für HTTP/3 ein. Sie ist zwar noch im Versuchsstadium, aber funktionsfähig, und das zeigt, dass der Prozess der Entwicklung neuer Internet-Standards funktioniert. Unter Federführung der Internet Engineering Task Force können Branchenpartner, Wettbewerber und andere wichtige Beteiligte gemeinsam Standards erarbeiten, die dem gesamten Internet zugute kommen, nicht nur den Giganten.

Eric Rescorla, der CTO von Firefox, bringt es auf den Punkt: „Die Entwicklung eines neuen Netzwerkprotokolls ist schwierig. Damit sie gelingt, müssen alle Beteiligten zusammenarbeiten. In den letzten Jahren haben wir TLS 1.3 und jetzt HTTP/3 und QUIC in Zusammenarbeit mit Cloudflare und anderen Partnern aus der Branche erprobt. Durch die frühe serverseitige Unterstützung dieser Protokolle bei Cloudflare konnten wir Schwierigkeiten bei der Interoperabilität unserer clientseitigen Firefox-Implementierung besser ausräumen. Wir freuen uns darauf, das Internet gemeinsam sicherer und leistungsfähiger zu machen.“

Wie sind wir an diesen Punkt gekommen?

Bevor wir uns eingehender mit HTTP/3 beschäftigen, werfen wir einen kurzen Blick auf die Evolution von HTTP im Laufe der Jahre, damit wir besser verstehen, warum HTTP/3 gebraucht wird.

Alles begann 1996 mit der Veröffentlichung der Spezifikation HTTP/1.0 und damit der Definition des grundlegenden HTTP-Textübertragungsformats, wie wir es heute kennen (ich tue in diesem Beitrag einmal so, als hätte es HTTP/0.9 nie gegeben). In HTTP/1.0 wird für jeden Anfrage-/Antwortvorgang zwischen Clients und Servern eine neue TCP-Verbindung erstellt. Damit muss man bei allen Anfragen eine Latenz in Kauf nehmen, denn die TCP- und TLS-Handshakes werden vor jeder Anfrage abgeschlossen.

Schlimmer noch: Anstatt alle ausstehenden Daten nach dem Verbindungsaufbau so schnell wie möglich zu senden, erzwingt TCP eine Aufwärmphase, die als „Slow Start“ bezeichnet wird. Dadurch kann der TCP-Algorithmus zur Engpasssteuerung jederzeit die Datenmenge bestimmen, die im Netzwerk unterwegs ist, und Überlastungen des Netzwerkpfads vorbeugen. So wird das Netzwerk nicht mit Paketen überflutet, die es nicht bewältigen kann. Da neue Verbindungen diesen langsamen Startvorgang durchlaufen müssen, können sie die gesamte verfügbare Netzwerkbandbreite nicht sofort nutzen.

Mit der Revision HTTP/1.1 der HTTP-Spezifikation wurde einige Jahre später versucht, diese Probleme durch die Einführung des Konzepts des „Keep-Alive“ von Verbindungen zu lösen. Damit können Clients TCP-Verbindungen wiederverwenden, sodass der Aufwand für den anfänglichen Verbindungsaufbau und den „Slow Start“ bei mehreren Anfragen weniger ins Gewicht fällt. Aber dies war kein Allheilmittel. Zwar konnten mehrere Anfragen dieselbe Verbindung gemeinsam nutzen, mussten aber serialisiert werden; ein Client und ein Server konnten bei jeder Verbindung also jeweils nur einen einzelnen Anfrage-/Antwortvorgang ausführen.

Im Laufe der Entwicklung des Webs mussten Browser beim Abruf und Aufbau von Webseiten immer stärker parallel arbeiten, denn die Anzahl der Ressourcen (CSS, JavaScript, Bilder …) für die einzelnen Websites hat im Laufe der Jahre zugenommen. Da Clients unter HTTP/1.1 jedoch jeweils nur einen HTTP-Anfrage-/Antwortvorgang durchführen konnten, gab es nur eine Möglichkeit für Parallelität auf Netzwerkebene: man musste mehrere TCP-Verbindungen parallel zum gleichen Ausgangspunkt einsetzen. Damit waren die meisten Vorteile der Keep-Alive-Verbindungen dahin. Verbindungen konnten zwar immer noch in einem gewissen (aber geringeren) Ausmaß wiederverwendet werden, aber im Grunde standen wir wieder am Anfang.

Mehr als ein Jahrzehnt später kamen schließlich SPDY und dann HTTP/2. Mit ihnen wurde unter anderem das Konzept von HTTP-„Streams“ eingeführt: eine Abstraktion, mit der HTTP-Implementierungen verschiedene HTTP-Austauschvorgänge auf der gleichen TCP-Verbindung „multiplexen“, also quasi gleichzeitig durchführen können. So konnten Browser TCP-Verbindungen effizienter wiederverwenden.

Aber auch das war noch kein Patentrezept! HTTP/2 löst das Ausgangsproblem – die ineffiziente Nutzung einer einzelnen TCP-Verbindung –, da nun mehrere Anfragen/Antworten gleichzeitig über dieselbe Verbindung übertragen werden können. Alle Anfragen und Antworten sind jedoch gleichermaßen von Paketverlusten betroffen (z. B. aufgrund von Netzwerküberlastung), auch wenn die verlorenen Daten nur eine einzelne Anfrage betreffen. Dies liegt daran, dass die HTTP/2-Schicht zwar verschiedene HTTP-Austauschvorgänge auf separaten Streams absondern kann, TCP jedoch von dieser Abstraktion nichts weiß. TCP sieht nur einen Strom von Byte ohne besondere Bedeutung.

TCP hat die Aufgabe, den gesamten Bytestrom in der richtigen Reihenfolge von einem Endpunkt zum anderen zu befördern. Wenn ein TCP-Paket, in dem einige dieser Byte enthalten sind, auf dem Weg durch das Netzwerk verloren geht, entsteht eine Lücke im Stream. Wenn der Verlust erkannt wird, muss TCP diese füllen und das betroffene Paket dazu erneut senden. Während dies geschieht, kann keines der erfolgreich zugestellten Byte, die hinter die verlorenen gehören, an die Anwendung übermittelt werden, selbst wenn diese nicht verlorengegangen sind und zu einer ganz anderen HTTP-Anfrage gehören. So werden sie unnötig verzögert, denn TCP kann nun einmal nicht wissen, ob die Anwendung sie ohne die fehlenden Bit verarbeiten könnte. Dieses Problem wird als „Head-of-Line-Blocking“ bezeichnet.

Vorhang auf für HTTP/3

Hier kommt HTTP/3 ins Spiel: Anstatt TCP als Transportschicht für die Sitzung zu verwenden, verwendet es QUIC, ein neues Internet-Transportprotokoll. Damit ändert sich unter anderem die Behandlung von Streams auf der Transportschicht. QUIC-Streams nutzen dieselbe QUIC-Verbindung, sodass keine zusätzlichen Handshakes und „Slow Starts“ erforderlich sind, um neue zu erstellen. QUIC-Streams werden außerdem unabhängig voneinander übermittelt, sodass in den meisten Fällen Paketverluste, die einen Stream betreffen, keine Auswirkungen auf andere haben. Dies ist möglich, weil QUIC-Pakete auf UDP-Datagrammen eingekapselt werden.

UDP erlaubt viel mehr Flexibilität als TCP, da QUIC-Implementierungen damit vollständig im Userspace existieren können. Wenn sich die Protokollimplementierung ändert, muss deswegen nicht das Betriebssystem aktualisiert werden, wie dies bei TCP der Fall ist. Mit QUIC können Streams auf HTTP-Ebene einfach auf QUIC-Streams abgebildet werden. So bekommt man alle Vorteile von HTTP/2, aber ohne Head-of-Line-Blocking.

QUIC kombiniert außerdem den typischen Drei-Wege-Handshake von TCP mit dem Handshake von TLS 1.3. Durch die Kombination dieser Schritte werden Verschlüsselung und Authentifizierung standardmäßig bereitgestellt, und auch ein schnellerer Verbindungsaufbau ist möglich. Mit anderen Worten, selbst wenn man für die ursprüngliche Anfrage in einer HTTP-Sitzung eine neue QUIC-Verbindung braucht, ist die Latenz vor dem Übertragen der Daten geringer als die von TCP mit TLS.

Aber warum nicht einfach HTTP/2 über QUIC verwenden, anstatt eine ganz neue HTTP-Überarbeitung zu erstellen? Schließlich bietet HTTP/2 ebenfalls die Stream-Multiplexing-Funktion. Wie sich herausgestellt hat, sind die Dinge etwas komplizierter.

Es stimmt zwar, dass einige der HTTP/2-Funktionen sehr einfach auf QUIC abgebildet werden können, aber eben nicht alle. Insbesondere das HTTP/2-Header-Kompressionsverfahren namens HPACK ist stark davon abhängig, in welcher Reihenfolge verschiedene HTTP-Anfragen und -Antworten an die Endpunkte übermittelt werden. QUIC gewährleistet die Reihenfolge der Übermittlung von Byte innerhalb einzelner Streams, garantiert jedoch nicht die Reihenfolge verschiedener Streams.

Wegen dieses Verhaltens musste ein neues HTTP-Header-Kompressionsverfahren namens QPACK entwickelt werden. Es behebt das Problem, erfordert aber Änderungen am HTTP-Mapping. Darüber hinaus werden einige der von HTTP/2 angebotenen Funktionen (wie die Ablaufsteuerung pro Stream) bereits von QUIC selbst angeboten. Deshalb wurden sie aus HTTP/3 entfernt, um das Protokoll nicht ohne Not zu verkomplizieren.

HTTP/3 mit einer leckeren Quiche

QUIC und HTTP/3 sind sehr spannende Standards, mit denen viele Schwächen früherer Standards behoben wurden und das Web eine ganz neue Performance erleben wird. Aber wie kommen wir von den spannenden Standarddokumenten zu einer funktionierenden Implementierung?

Cloudflares QUIC- und HTTP/3-Unterstützung wird durch quiche gewährleistet, unsere eigene Open-Source-Implementierung, die in Rust geschrieben wurde.

Sie finden sie auf GitHub unter github.com/cloudflare/quiche.

Seit wir vor einigen Monaten quiche angekündigt haben, ist zur vorhandenen QUIC-Unterstützung auch die Unterstützung für das HTTP/3-Protokoll dazugekommen. Wir haben quiche so konzipiert, dass man damit jetzt HTTP/3-Clients und -Server oder einfach nur QUIC-Clients implementieren kann.

Wie aktiviere ich HTTP/3 für meine Domain?

Wie bereits erwähnt, haben wir angefangen, Kunden einzubinden, die auf der Warteliste stehen. Wenn Sie auch auf der Warteliste stehen und von uns per E-Mail erfahren haben, dass Sie die Funktion jetzt für Ihre Websites aktivieren können, rufen Sie einfach das Cloudflare-Dashboard auf und schalten Sie HTTP/3 einfach auf der Registerkarte „Netzwerk“ ein:

Wir gehen davon aus, dass die HTTP/3-Funktion in naher Zukunft allen Kunden zur Verfügung stehen wird.

Nach der Aktivierung haben Sie verschiedene Möglichkeiten, mit HTTP/3 zu experimentieren:

Google Chrome als HTTP/3-Client verwenden

Um mit Chrome eine HTTP/3-Verbindung zu Ihrer Website herzustellen, müssen Sie zunächst das neueste Canary-Build herunterladen und installieren. Zur Aktivierung der HTTP/3-Unterstützung müssen Sie Chrome Canary dann nur noch mit den Befehlszeilenargumenten „--enable-quic“ und „--quic-version=h3-23“ starten.

Sobald Chrome mit den erforderlichen Argumenten gestartet wurde, können Sie einfach Ihre Domain in die Adressleiste eingeben und miterleben, wie sie über HTTP/3 geladen wird (in der Registerkarte „Netzwerk“ in den Entwicklertools von Chrome können Sie sehen, welche Protokollversion verwendet wurde). Beachten Sie, dass die ersten Verbindungen mit der Domain möglicherweise noch nicht über HTTP/3 hergestellt werden. Das liegt daran, dass Browser und Server sich anfangs noch über das Protokoll abstimmen müssen. Laden Sie die Seite dann einfach mehrmals neu.

Wenn Ihnen das zu kompliziert erscheint, keine Sorge. Die HTTP/3-Unterstützung in Chrome wird im Laufe der Zeit stabiler werden, und die Aktivierung von HTTP/3 einfacher.

Wenn Sie diesen Blog über HTTP/3 aufrufen, sehen Sie in den Entwicklertools in der Registerkarte „Netzwerk“ Folgendes:

Screen-Shot-2019-09-20-at-1.27.34-PM

Beachten Sie, dass aufgrund der experimentellen Natur der HTTP/3-Unterstützung in Chrome das Protokoll in den Entwicklertools tatsächlich als „http2+quic/99“ bezeichnet wird. Das täuscht, es ist tatsächlich HTTP/3.

curl verwenden

Das Befehlszeilentool curl unterstützt ebenfalls HTTP/3 als experimentelles Feature. Sie müssen die neueste Version von git herunterladen und nach der Anleitung zum Aktivieren der HTTP/3-Unterstützung vorgehen.

Auch auf macOS können Sie über Homebrew problemlos eine HTTP/3-fähige Version von curl installieren:

 % brew install --HEAD -s https://raw.githubusercontent.com/cloudflare/homebrew-cloudflare/master/curl.rb

Um eine HTTP/3-Anfrage auszuführen, müssen Sie nur das Befehlszeilenflag „--http3“ an einen normalen curl-Befehl anhängen:

 % ./curl -I https://blog.cloudflare.com/ --http3
HTTP/3 200
date: Tue, 17 Sep 2019 12:27:07 GMT
content-type: text/html; charset=utf-8
set-cookie: __cfduid=d3fc7b95edd40bc69c7d894d296564df31568723227; expires=Wed, 16-Sep-20 12:27:07 GMT; path=/; domain=.blog.cloudflare.com; HttpOnly; Secure
x-powered-by: Express
cache-control: public, max-age=60
vary: Accept-Encoding
cf-cache-status: HIT
age: 57
expires: Tue, 17 Sep 2019 12:28:07 GMT
alt-svc: h3-23=":443"; ma=86400
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 517b128df871bfe3-MAN

Den HTTP/3-Client von quiche verwenden

Abschließend haben wir auf quiche auch einen Muster-HTTP/3-Befehlszeilen-Client (sowie einen Befehlszeilenserver) bereitgestellt, mit dem Sie mit HTTP/3 experimentieren können.

Um ihn zum Laufen zu bringen, müssen Sie zunächst das GitHub-Repository von quiche klonen:

$ git clone --recursive https://github.com/cloudflare/quiche

Führen Sie dann das Build durch. Sie benötigen eine funktionierende Rust- und Cargo-Installation, damit dies funktioniert (wir empfehlen die Verwendung von rustup; damit können Sie mühelos eine funktionierende Rust-Entwicklungsumgebung einrichten).

$ cargo build --examples

Und nun können Sie eine HTTP/3-Anfrage ausführen:

$ RUST_LOG=info target/debug/examples/http3-client https://blog.cloudflare.com/

Wie geht es weiter?

In den kommenden Monaten werden wir unsere QUIC- und HTTP/3-Implementierung weiter verbessern und optimieren und diese neue Funktion schließlich allen zur Verfügung stellen, ohne dass man sich dafür in eine Warteliste eintragen muss. Im Rahmen weiterer Standardentwicklungen werden wir unsere Implementierung immer wieder aktualisieren. Zwischen den Entwurfsversionen der Standards kann es dadurch zu inkompatiblen Änderungen (breaking changes) kommen.

Hier ein paar neue Features aus unserer Roadmap, auf die wir uns besonders freuen:

Verbindungsmigration

Ein wichtiges Feature, das durch QUIC erst möglich wird, ist der nahtlose und transparente Übergang von Verbindungen zwischen verschiedenen Netzwerken (z. B. Ihrem Heim-WLAN und dem Mobilfunknetz Ihres Mobilfunkanbieters, wenn Sie morgens zur Arbeit gehen), ohne dass dafür eine ganz neue Verbindung aufgebaut werden muss.

Diese Funktion erfordert einige zusätzliche Änderungen an unserer Infrastruktur, aber wir freuen uns, unseren Kunden dies in Zukunft bieten zu können.

Roundtrip ohne Zeitverlust

Genau wie TLS 1.3 unterstützt QUIC einen Betriebsmodus, durch den Clients schon vor Abschluss des Verbindungshandshakes mit dem Senden von HTTP-Anfragen beginnen können. Wir unterstützen diese Funktion in unserer QUIC-Bereitstellung noch nicht, aber wir werden daran arbeiten, genau wie bei unserer TLS 1.3-Unterstützung.

HTTP/3: es läuft!

Wir freuen uns sehr darüber, dass wir HTTP/3 bereits unterstützen und unseren Kunden für ihre Experimente zur Verfügung stellen können, während die Standardisierung von QUIC und HTTP/3 noch andauert. Wir werden weiterhin mit anderen Organisationen zusammenarbeiten, darunter Google und Mozilla, um die QUIC- und HTTP/3-Standards abschließend festzulegen und ihre breite Akzeptanz zu fördern.

Damit das Web für alle schneller, zuverlässiger und sicherer wird.