sgcQUIC in fünf Minuten

QUIC und HTTP/3 in nativem Object Pascal, auf der QUIC-Engine in OpenSSL. Es gibt vier Komponenten. Der kürzeste Weg zu etwas Lauffähigem ist der HTTP/3-Client, daher sendet diese Seite eine Anfrage, liest den Statuscode und ist genau dabei, welches OpenSSL du brauchst.

QUIC RFC 9000 und HTTP/3 RFC 9114
OpenSSL 3.2 und höher für den Client
All-Access-Edition

Was die erste Anfrage benötigt

Eine Komponente, eine URL und zwei OpenSSL-Bibliotheken neben deiner ausführbaren Datei.

Komponente

TsgcHTTP3Client auf der Palettenseite SGC QUIC, deklariert in sgcQUIC.pas. Die Seite enthält außerdem TsgcQUICClient, TsgcQUICServer und TsgcHTTP3Server.

Unit

sgcQUIC für die Komponente. Füge sgcHTTP3_Classes für TsgcHTTP3Response hinzu, und sgcHTTP_AltSvc, wenn du das Alt-Svc-Ereignis behandelst.

Der Aufruf

Get(aURL) liefert den Body als string zurück und löst bei einem Fehler eine Exception aus. Statuscode und Header kommen getrennt, über OnResponse.

Die OpenSSL-Voraussetzung

Der Client braucht die QUIC-API aus OpenSSL 3.2 oder höher oder einen quictls-Build. Der Server braucht 3.5 oder höher, weil er eine API aufruft, die nur dort existiert. Liefere libcrypto-3.dll und libssl-3.dll neben deiner ausführbaren Datei aus, so wie es jeder Demo-Ordner tut.

Voraussetzungen und Editionen

Die Editionsspalte nennt das Define, das den Code steuert, samt der Zeile in Source/sgcVer.inc, in der es steht.

Was Wert
IDE Delphi 7 bis RAD Studio 13 sowie C++Builder 2007 bis 13. Es gibt keinen separaten sgcQUIC-Download: Die Komponenten befinden sich in der Paketgruppe von sgcWebSockets.
Uses-Klausel sgcQUIC, dazu sgcHTTP3_Classes für das Response-Objekt und sgcHTTP_AltSvc für die Alt-Svc-Typen.
Pack-Define SGC_PACK_QUIC wird in Zeile 872 definiert, innerhalb des Blocks {$IFDEF SGC_EDT_ALL}, der von Zeile 870 bis Zeile 874 reicht. Also All-Access.
Funktions-Defines Innerhalb des Blocks {$IFDEF SGC_PACK_QUIC} in den Zeilen 894 bis 899: SGC_QUIC in Zeile 896, SGC_HTTP3 in Zeile 897 und SGC_WEBTRANSPORT in Zeile 898. Alle drei liegen innerhalb eines {$IFDEF SGC_INDY_LIB} in Zeile 895, ein Build ohne die benutzerdefinierte Indy-Bibliothek erhält also keines davon.
OpenSSL, Client 3.2 oder höher oder ein quictls-Build. Die Bibliothek sagt es selbst: Der Fehler, der ausgelöst wird, wenn QUIC nicht verfügbar ist, lautet QUIC is not available. Requires quictls/openssl or OpenSSL 3.2+.
OpenSSL, Server 3.5 oder höher. Der QUIC-Server ruft SSL_new_listener auf, und der Fehler, der ausgelöst wird, wenn dieser Aufruf fehlt, lautet QUIC Server requires OpenSSL 3.5 or later. msquic wird nicht verwendet und wird nicht benötigt.
Plattformen Kein Plattform-Guard auf Unit-Ebene in sgcQUIC.pas, sgcQUIC_Client.pas, sgcHTTP3_Client.pas oder sgcHTTP3_Server.pas, und alle vier Komponenten sind mit ComponentPlatforms(0) registriert. Die Server-Unit wählt die Socket-API je Plattform, mit einem Windows- und einem POSIX-Zweig.

Du bist nicht sicher, ob die Engine zur Laufzeit vorhanden ist? Rufe IsOpenSSL_QUIC_Available auf, das zurückgibt, ob das geladene OpenSSL die QUIC-Client-Methode bereitstellt. Die mitgelieferte QUIC-Client-Demo protokolliert es genau aus diesem Grund beim Start.

Installieren und die Palettenseite finden

Es gibt keinen separaten sgcQUIC-Installer. Die Komponenten kommen mit sgcWebSockets und erscheinen, sobald die Edition sie freischaltet.

1. Entpacken

Entpacke den sgcWebSockets-Download in einen Ordner, unten {$DIR} genannt.

2. Bibliothekspfad

Tools, Optionen, Bibliothek. Füge {$DIR}\source und den lib-Ordner für deine IDE hinzu, zum Beispiel {$DIR}\libD13\$(Platform).

3. Pakete erstellen

Öffne die Paketgruppe für deine IDE-Version unter {$DIR}\Packages\. Kompiliere zuerst das Laufzeit-.dpk und installiere dann das Entwurfszeitpaket mit dcl. Es gibt kein QUIC-spezifisches Paket.

4. Palette prüfen

Es erscheint eine Seite namens SGC QUIC mit TsgcQUICClient, TsgcQUICServer, TsgcHTTP3Client und TsgcHTTP3Server. Fehlt die Seite, ist der Build nicht All-Access, denn SGC_PACK_QUIC wird nur in Zeile 872 innerhalb dieses Blocks definiert.

5. OpenSSL neben die exe legen

Kopiere libcrypto-3.dll und libssl-3.dll neben deine ausführbare Datei, 3.2 oder höher für einen Client und 3.5 oder höher für einen Server. Jeder Ordner unter Demos\22.QUIC_Protocol enthält sie, du kannst sie also von dort kopieren.

Eine HTTP/3-Anfrage

Erzeuge den Client, verdrahte drei Ereignisse, rufe Get auf. Die Antwort kommt als String zurück und der Statuscode trifft in OnResponse ein.

FHTTP3Client.pas
uses
  Classes, SysUtils,
  // sgc
  sgcQUIC, sgcHTTP3_Classes;

procedure TfrmHTTP3Client.FormCreate(Sender: TObject);
begin
  FClient := TsgcHTTP3Client.Create(nil);
  FClient.OnConnect := OnH3Connect;
  FClient.OnError := OnH3Error;
  FClient.OnResponse := OnH3Response;
  FClient.TLSOptions.VerifyCertificate := True;
  FClient.ConnectTimeout := 10000;
  FClient.ReadTimeout := 30000;
  FClient.UserAgent := 'sgcWebSockets/HTTP3Client';
end;

procedure TfrmHTTP3Client.btnGetClick(Sender: TObject);
var
  vResult: string;
begin
  try
    // the target comes from the URL, because Host and Port
    // are read-only on this component
    vResult := FClient.Get('https://www.google.com/');
    memoBody.Lines.Text := vResult;
    DoLog('Response received: ' + IntToStr(Length(vResult)) + ' bytes');
  except
    on E: Exception do
      DoLog('Error: ' + E.Message);
  end;
end;

Post, Put und Delete haben dieselbe Form, und jede hat eine Stream-Überladung für einen Body, den du nicht in einem String halten möchtest. Connect(const aHost: string; aPort: Integer = 443) öffnet die Verbindung vor der ersten Anfrage, wenn du beides trennen willst.

FHTTP3Client.pas
// OnConnect and OnDisconnect are plain TNotifyEvent on this
// component: one parameter, no connection object.
procedure TfrmHTTP3Client.OnH3Connect(Sender: TObject);
begin
  DoLog('Connected to ' + FClient.Host + ':' + IntToStr(FClient.Port));
end;

procedure TfrmHTTP3Client.OnH3Error(Sender: TObject; const aError: string);
begin
  DoLog('Error: ' + aError);
end;

procedure TfrmHTTP3Client.OnH3Response(Sender: TObject;
  const aResponse: TsgcHTTP3Response);
begin
  DoLog('Status: ' + IntToStr(aResponse.StatusCode));
  memoHeaders.Lines.Assign(aResponse.Headers);
end;

FClient.Host und FClient.Port innerhalb von OnConnect zu lesen, ist genau das, wofür diese beiden Eigenschaften da sind. Sie melden die Verbindung, sie konfigurieren sie nicht.

FQUICClient.pas
uses
  Classes, SysUtils,
  // sgc
  sgcIdSSLOpenSSLHeaders;

procedure TfrmQUICClient.FormCreate(Sender: TObject);
begin
  DoLog('OpenSSL QUIC Support:');
  DoLog('  quictls API: ' +
    BoolToStr(IsOpenSSL_QUIC_TLS_Available, True));
  DoLog('  Builtin QUIC (3.2+): ' +
    BoolToStr(IsOpenSSL_QUIC_Available, True));
end;

Führe dies einmal vor allem anderen aus. Wenn beide false melden, hat das OpenSSL neben deiner ausführbaren Datei kein QUIC, und jeder weitere Verbindungsfehler ist ein Symptom dieser einen Tatsache und nicht des Netzwerks.

Die ersten beiden Tabs stammen aus der mitgelieferten Demo Demos\22.QUIC_Protocol\03.HTTP3_Client\FHTTP3Client.pas, wobei die Formularsteuerelemente durch Literale ersetzt wurden. Der dritte ist die Laufzeitprüfung der Verfügbarkeit aus 01.QUIC_Client\FQUICClient.pas. In diesem Ordner liegen sechs QUIC-Demos, darunter ein WebTransport-Paar.

Den Statuscode lesen, nicht nur den Body

Get liefert den Body. Das Response-Objekt trägt alles andere, und es kommt über ein eigenes Ereignis.

Der Rückgabewert

Get liefert den Antwort-Body als string zurück und löst bei einem Fehler eine Exception aus, deshalb steckt die Demo es in ein try except. Ein Body in der erwarteten Länge ist der erste Beleg.

OnResponse

procedure(Sender: TObject; const aResponse: TsgcHTTP3Response). StatusCode ist die Zahl, die du tatsächlich willst, Headers ist eine TStringList, und GetDataAsString liefert dir den Body noch einmal aus dem Response-Objekt.

OnConnect

Ein einfaches TNotifyEvent. Dass es überhaupt ausgelöst wird, bedeutet, dass QUIC ausgehandelt und die HTTP/3-Sitzung geöffnet wurde, und genau das scheitert beim ersten Lauf am wahrscheinlichsten.

Bevor du den Code beschuldigst

IsOpenSSL_QUIC_Available beantwortet die einzige Frage, die zuerst gestellt werden sollte. QUIC läuft außerdem über UDP 443, und ein Netzwerk, das TCP 443 erlaubt, erlaubt das nicht zwingend.

Was beim ersten Mal meistens schiefgeht

Sechs Probleme erklären fast jede fehlgeschlagene erste Anfrage.

Host oder Port lassen sich nicht zuweisen

Sie sind bei TsgcHTTP3Client schreibgeschützt, deklariert als property Host: string read FHost und property Port: Integer read FPort. Sie melden, wohin der Client verbunden ist. Um ein Ziel zu wählen, übergib Get eine vollständige URL oder rufe Connect(aHost, aPort) auf.

QUIC ist nicht verfügbar

Das geladene OpenSSL ist zu alt oder wurde ohne QUIC gebaut. Der Client braucht 3.2 oder höher, oder quictls. Prüfe zur Laufzeit mit IsOpenSSL_QUIC_Available, bevor du dem Netzwerk die Schuld gibst.

Der Server startet nicht

Der QUIC-Server braucht OpenSSL 3.5 oder höher, weil er SSL_new_listener aufruft. Ein 3.2-Build genügt für den Client und nicht für den Server, und die Fehlermeldung sagt das ausdrücklich.

Falsche Parameteranzahl bei OnConnect

OnConnect und OnDisconnect sind bei dieser Komponente einfache TNotifyEvent, der Handler nimmt also nur Sender: TObject entgegen. Anders als die WebSocket-Komponenten übergeben sie dir kein Verbindungsobjekt.

UDP ist blockiert

QUIC läuft über UDP auf Port 443, und viele Unternehmensnetzwerke erlauben TCP 443 und verwerfen UDP 443. Wenn ein Browser den Host über HTTP/3 erreichen kann und deine Anwendung nicht, verdächtige die Firewall vor dem Code.

Die Palettenseite fehlt

SGC_PACK_QUIC wird nur in Zeile 872 innerhalb des All-Access-Blocks definiert. Es setzt außerdem SGC_INDY_LIB voraus, weil der gesamte Pack-Block in den Zeilen 894 bis 899 in diesem Guard liegt.

Über die erste Anfrage hinaus

Vier Richtungen, alle im selben Paket.

Einen HTTP/3-Server betreiben

TsgcHTTP3Server liefert HTTP/3 direkt über QUIC aus. Denk an die Untergrenze OpenSSL 3.5 auf der Serverseite.

HTTP/3-Server-Komponente

Rohes QUIC, ohne HTTP

TsgcQUICClient und TsgcQUICServer geben dir QUIC-Streams ohne die HTTP/3-Schicht, was du für ein eigenes Protokoll willst, das Multiplexing ohne Head-of-Line-Blocking braucht.

QUIC-Client und QUIC-Server

WebTransport

Bidirektionale Streams und Datagramme zu einem Browser über HTTP/3, gesteuert durch SGC_WEBTRANSPORT in Zeile 898. Zwei Demos liegen bei.

sgcQUIC-Funktionen

HTTP/3 aus HTTP/2 entdecken

Ein Server bewirbt HTTP/3 mit einem Alt-Svc-Header. Behandle OnAltSvc, und du kannst eine bestehende Verbindung auf QUIC hochstufen, wenn der Ursprung es anbietet.

HTTP/2-Client

Referenz, Demos und Dokumentation

Die Demo-Projekte liegen im Download unter Demos\22.QUIC_Protocol. Es sind sechs.

HTTP/3-Client-Komponente Was TsgcHTTP3Client bereitstellt, Eigenschaft für Eigenschaft.
HTTP/3-Server-Komponente Die Serverseite, einschließlich der Voraussetzung OpenSSL 3.5.
QUIC-Client-Komponente Rohe QUIC-Streams ohne die HTTP/3-Schicht.
sgcQUIC-Funktionen QPACK, 0-RTT, Verbindungsmigration, WebTransport und der Rest.
Testversion herunterladen Ein Installer pro IDE-Version, die QUIC-Komponenten sind bereits enthalten.
Online-Hilfe Die generierte Referenz, stets auf dem Stand der aktuellen Version.

Zum Weiterlesen: die QUIC-Client- und Server-Komponenten und die HTTP/3-Komponenten. Wenn du zwischen Transporten wählst, vergleicht der Leitfaden zu Echtzeit-Transporten sie. Jedes Produkt hat einen eigenen Schnellstart, aufgelistet auf der Seite Erste Schritte.

Fragen zum sgcQUIC-Schnellstart

TsgcHTTP3Client aus der Unit sgcQUIC auf der Palettenseite SGC QUIC. Füge sgcHTTP3_Classes für TsgcHTTP3Response hinzu, den Parametertyp von OnResponse, und sgcHTTP_AltSvc, wenn du OnAltSvc behandelst. Die Palettenseite enthält außerdem TsgcQUICClient, TsgcQUICServer und TsgcHTTP3Server.
Das hängt davon ab, welche Seite du baust. Der Client braucht die in OpenSSL 3.2 hinzugefügte QUIC-API oder einen quictls-Build, und die Bibliothek sagt das in ihrer Fehlermeldung: QUIC is not available. Requires quictls/openssl or OpenSSL 3.2+. Der Server braucht 3.5 oder höher, weil er SSL_new_listener aufruft, und seine Fehlermeldung nennt diese Version ausdrücklich. Liefere libcrypto-3.dll und libssl-3.dll neben deiner ausführbaren Datei aus. msquic wird nicht verwendet.
Weil sie schreibgeschützt sind. TsgcHTTP3Client deklariert sie als property Host: string read FHost und property Port: Integer read FPort, sie melden also die aktuelle Verbindung, statt sie zu konfigurieren. Übergib eine vollständige URL an Get, Post, Put oder Delete, oder rufe zuerst Connect(const aHost: string; aPort: Integer = 443) auf.
Ein einfaches TNotifyEvent, also procedure(Sender: TObject). Dasselbe gilt für OnDisconnect. Das unterscheidet sich von den WebSocket-Komponenten, deren Ereignisse dir ein TsgcWSConnection übergeben, und ist eine häufige Quelle für einen Compilerfehler im ersten Projekt. OnResponse ist procedure(Sender: TObject; const aResponse: TsgcHTTP3Response) und OnError ist procedure(Sender: TObject; const aError: string).
Aus dem Response-Objekt in OnResponse. TsgcHTTP3Response stellt StatusCode, Headers als TStringList und GetDataAsString für den Body bereit. Die Methode Get selbst liefert nur den Body als String, weshalb die Demo zusätzlich OnResponse verdrahtet.
SGC_PACK_QUIC wird in Zeile 872 von sgcVer.inc definiert, innerhalb des Blocks {$IFDEF SGC_EDT_ALL}, der von Zeile 870 bis Zeile 874 reicht. Also All-Access. Der Pack-Block selbst, Zeilen 894 bis 899, liegt außerdem in einem {$IFDEF SGC_INDY_LIB}, die benutzerdefinierte Indy-Bibliothek muss also ebenfalls Teil des Builds sein. Innerhalb dieses Blocks ist SGC_QUIC Zeile 896, SGC_HTTP3 Zeile 897 und SGC_WEBTRANSPORT Zeile 898.
Nein. Der Test-Installer gilt pro IDE-Version und enthält bereits die QUIC- und HTTP/3-Komponenten, und es gibt keine QUIC-spezifische Paketdatei. Installiere sgcWebSockets, und die Palettenseite SGC QUIC erscheint, wenn die Edition sie freischaltet.
Ja, und das solltest du. IsOpenSSL_QUIC_Available gibt zurück, ob das geladene OpenSSL die QUIC-Client-Methode bereitstellt, und IsOpenSSL_QUIC_TLS_Available tut dasselbe für die QUIC-TLS-Callbacks. Die mitgelieferte QUIC-Client-Demo schreibt beide beim Start in ihr Log, was einen rätselhaften Verbindungsfehler in eine Ein-Zeilen-Antwort verwandelt.
Bestes Preis-Leistungs-Verhältnis: All-AccessAlle eSeGeCe-Produkte, inklusive Premium-Support, ab €1,059 pro Jahr.
All-Access-Preise ansehen

Bereit, HTTP/3 aus Delphi auszuprobieren?

Lade die Testversion herunter und führe die HTTP/3-Client-Demo gegen einen echten Ursprungsserver aus.