====== std.net.http ======
HTTP/1.1-Client für GET, POST, PUT, DELETE, PATCH und HEAD ohne TLS. Baut auf ''std.net.socket'' und ''std.net.dns'' auf. Unterstützt Header-Builder (''HTTPSetHeader''), Bearer- und Basic-Auth (RFC 7617), automatisches Chunked-Transfer-Decoding, 3×x-Redirects (HTTP→HTTP und HTTP→HTTPS, bis 10 Hops) sowie case-insensitives Header-Lesen. Für HTTPS-Verbindungen ''[[lyx_-_programmiersprache:units:net:https|std.net.https]]'' verwenden.
import std.net.http;
var hdrs: int64 := HTTPSetBearerToken(0, "my-token");
var req: HTTPRequest;
req.method := HTTP_GET;
req.host := "api.example.com" as int64;
req.path := "/v1/items" as int64;
req.port := HTTP_PORT;
req.headers := hdrs;
var resp: HTTPResponse := HTTPSendWithRedirects(req);
if (resp.statusCode = HTTP_OK) {
PrintLn("OK");
}
HTTPResponseFree(resp);
HTTPHeadersFree(hdrs);
----
===== Imports =====
* ''std.net.socket''
* ''std.net.dns''
* ''std.net.types''
* ''std.string''
* ''std.base64''
----
===== Konstanten =====
^ Name ^ Typ ^ Wert ^ Sichtbarkeit ^
| ''HTTP_PORT'' | ''int64'' | ''80'' | pub |
| ''HTTPS_PORT'' | ''int64'' | ''443'' | pub |
| ''HTTP_RECV_TIMEOUT_MS'' | ''int64'' | ''30000'' | pub |
| ''HTTP_MAX_REDIRECTS'' | ''int64'' | ''10'' | pub |
| ''HTTP_GET'' | ''int64'' | ''1'' | pub |
| ''HTTP_POST'' | ''int64'' | ''2'' | pub |
| ''HTTP_PUT'' | ''int64'' | ''3'' | pub |
| ''HTTP_DELETE'' | ''int64'' | ''4'' | pub |
| ''HTTP_PATCH'' | ''int64'' | ''5'' | pub |
| ''HTTP_HEAD'' | ''int64'' | ''6'' | pub |
| ''HTTP_OK'' | ''int64'' | ''200'' | pub |
| ''HTTP_CREATED'' | ''int64'' | ''201'' | pub |
| ''HTTP_NO_CONTENT'' | ''int64'' | ''204'' | pub |
| ''HTTP_BAD_REQUEST'' | ''int64'' | ''400'' | pub |
| ''HTTP_UNAUTHORIZED'' | ''int64'' | ''401'' | pub |
| ''HTTP_FORBIDDEN'' | ''int64'' | ''403'' | pub |
| ''HTTP_NOT_FOUND'' | ''int64'' | ''404'' | pub |
| ''HTTP_SERVER_ERROR'' | ''int64'' | ''500'' | pub |
----
===== Typen =====
==== HTTPResponse (struct) ====
^ Feld ^ Typ ^ Beschreibung ^
| ''statusCode'' | ''int64'' | HTTP-Statuscode (z. B. 200, 404) |
| ''statusText'' | ''int64'' | Zeiger auf Statustext-String (z. B. "OK") |
| ''headerCount'' | ''int64'' | Anzahl der geparsten Response-Header |
| ''contentLength'' | ''int64'' | Content-Length aus Header (−1 wenn nicht vorhanden) |
| ''bodyPtr'' | ''int64'' | Zeiger auf Response-Body (heap-alloc'd) |
| ''bodySize'' | ''int64'' | Tatsächliche Größe des Body in Bytes |
| ''headersRaw'' | ''int64'' | Zeiger auf rohe Response-Header (null-terminiert, heap-alloc'd) |
| ''headersSize'' | ''int64'' | Byte-Anzahl der rohen Header |
==== HTTPRequest (struct) ====
^ Feld ^ Typ ^ Beschreibung ^
| ''method'' | ''int64'' | HTTP-Methode (''HTTP_GET'', ''HTTP_POST'' …) |
| ''host'' | ''int64'' | Zeiger auf Hostname-String |
| ''path'' | ''int64'' | Zeiger auf Pfad-String (inkl. führendem ''/'' und Query) |
| ''port'' | ''int64'' | TCP-Port (''HTTP_PORT'' = 80) |
| ''headers'' | ''int64'' | Zeiger auf Header-String (aus ''HTTPSetHeader'') oder ''0'' |
| ''body'' | ''int64'' | Zeiger auf Request-Body oder ''0'' |
| ''bodySize'' | ''int64'' | Länge des Request-Body in Bytes |
----
===== Funktionen =====
==== Einfache Convenience-Funktionen ====
^ Signatur ^ Sichtbarkeit ^ Beschreibung ^
| ''HTTPGet(host: int64, path: int64): HTTPResponse'' | pub | HTTP-GET an Host senden |
| ''HTTPPost(host: int64, path: int64, body: int64, bodySize: int64): HTTPResponse'' | pub | HTTP-POST mit Body senden |
| ''HTTPPut(host: int64, path: int64, body: int64, bodySize: int64): HTTPResponse'' | pub | HTTP-PUT mit Body senden |
| ''HTTPDelete(host: int64, path: int64): HTTPResponse'' | pub | HTTP-DELETE senden |
| ''HTTPPatch(host: int64, path: int64, body: int64, bodySize: int64): HTTPResponse'' | pub | HTTP-PATCH mit Body senden |
| ''HTTPHead(host: int64, path: int64): HTTPResponse'' | pub | HTTP-HEAD senden (kein Body in Antwort) |
==== Header-Varianten (mit vorgebautem Header-String) ====
^ Signatur ^ Sichtbarkeit ^ Beschreibung ^
| ''HTTPGetH(host: int64, path: int64, headers: int64): HTTPResponse'' | pub | HTTP-GET mit zusätzlichen Headern |
| ''HTTPPostH(host: int64, path: int64, body: int64, bodySize: int64, headers: int64): HTTPResponse'' | pub | HTTP-POST mit Body und Headern |
| ''HTTPDeleteH(host: int64, path: int64, headers: int64): HTTPResponse'' | pub | HTTP-DELETE mit Headern |
==== Request-Builder und Low-Level-API ====
^ Signatur ^ Sichtbarkeit ^ Beschreibung ^
| ''HTTPRequestBuild(req: HTTPRequest): int64'' | pub | HTTP-Anfrage-Puffer aus Struct aufbauen; gibt Zeiger auf Puffer zurück |
| ''HTTPSend(request: HTTPRequest): HTTPResponse'' | pub | HTTP-Anfrage senden; dekodiert automatisch Chunked Transfer-Encoding |
| ''HTTPSendWithRedirects(request: HTTPRequest): HTTPResponse'' | pub | Wie ''HTTPSend'', folgt aber automatisch 3×x-Redirects (bis ''HTTP_MAX_REDIRECTS'' = 10); HTTP→HTTPS via TLS |
==== Header-Builder ====
^ Signatur ^ Sichtbarkeit ^ Beschreibung ^
| ''HTTPSetHeader(hdrs: int64, name: int64, value: int64): int64'' | pub | Fügt Header-Zeile zu vorhandenem Header-String hinzu (oder legt neuen an wenn ''hdrs=0''); gibt neuen heap-alloc'd String zurück |
| ''HTTPHeadersFree(hdrs: int64)'' | pub | Gibt einen per ''HTTPSetHeader'' aufgebauten Header-String frei |
| ''HTTPSetBearerToken(hdrs: int64, token: int64): int64'' | pub | Fügt ''Authorization: Bearer '' hinzu; gibt neuen Header-String zurück |
| ''HTTPSetBasicAuth(hdrs: int64, user: int64, pass: int64): int64'' | pub | Fügt ''Authorization: Basic '' hinzu (RFC 7617); gibt neuen Header-String zurück |
==== Response-Zugriff ====
^ Signatur ^ Sichtbarkeit ^ Beschreibung ^
| ''HTTPGetHeader(resp: HTTPResponse, name: int64): int64'' | pub | Sucht Header ''name'' im ''headersRaw''-Puffer; **case-insensitiv**; gibt Zeiger auf Header-Wert zurück oder ''0'' wenn nicht gefunden |
| ''HTTPResponseFree(response: HTTPResponse)'' | pub | Gibt Body-Puffer **und** ''headersRaw'' frei |
----
===== Codebeispiele =====
==== PUT mit Bearer-Token ====
var hdrs: int64 := HTTPSetBearerToken(0, "eyJhbGci...");
var body: pchar := "{\"status\":\"active\"}";
var resp: HTTPResponse := HTTPPostH(
"api.example.com" as int64, "/v1/item/42" as int64,
body as int64, StrLen(body), hdrs);
if (resp.statusCode = HTTP_OK) {
PrintLn("Aktualisiert");
}
HTTPResponseFree(resp);
HTTPHeadersFree(hdrs);
==== Response-Header lesen ====
var resp: HTTPResponse := HTTPGet("api.example.com" as int64, "/" as int64);
var ct: int64 := HTTPGetHeader(resp, "Content-Type" as int64);
if (ct != 0) {
PrintLn(ct as pchar);
}
HTTPResponseFree(resp);
==== Redirect-Folgen (HTTP → HTTPS) ====
var req: HTTPRequest;
req.method := HTTP_GET;
req.host := "example.com" as int64;
req.path := "/" as int64;
req.port := HTTP_PORT;
req.headers := 0;
req.body := 0;
req.bodySize := 0;
// Folgt automatisch: HTTP 301 → https://example.com/
var resp: HTTPResponse := HTTPSendWithRedirects(req);
HTTPResponseFree(resp);
----
===== Hinweise =====
* **Chunked Transfer-Encoding**: ''HTTPSend'' und alle darauf aufbauenden Funktionen dekodieren ''Transfer-Encoding: chunked'' automatisch — kein manuelles Chunk-Parsing nötig.
* **Redirects**: ''HTTPSendWithRedirects'' folgt 3×x-Antworten bis zu ''HTTP_MAX_REDIRECTS'' (10) Hops. Ein Wechsel von HTTP auf HTTPS (''Location: https://...'') wird transparent über TLS abgewickelt.
* **''HTTPSetHeader'' ist funktional**: Jeder Aufruf gibt einen **neuen** heap-alloc'd String zurück. Der alte Wert (Eingabe ''hdrs'') wird intern freigegeben — den Rückgabewert immer verwenden, nicht den alten ''hdrs''-Wert weiterverwenden.
* **''HTTPGetHeader'' ist case-insensitiv**: ''Content-Type'', ''content-type'' und ''CONTENT-TYPE'' liefern denselben Treffer.
* **''HTTPResponseFree'' gibt ''headersRaw'' frei**: Kein separates Freigeben nötig — ein Aufruf reicht für alle alloc'd Felder der Response.
* **Basic Auth (RFC 7617)**: ''HTTPSetBasicAuth'' berechnet ''base64(user:pass)'' intern — keine externe Base64-Funktion nötig.
* **TLS-Redirects**: Für den HTTPS-Hop im Redirect-Pfad muss ''std.net.tls'' verfügbar sein.
Letzte Aktualisierung: 2026-06-06