std.http — HTTP Client e Server
O módulo std.http fornece uma implementação completa de HTTP/1.1 na biblioteca padrão do Zig, incluindo tanto um cliente para fazer requisições quanto um servidor para recebê-las. Ele é construído sobre std.net e usa as interfaces de I/O do Zig, oferecendo suporte a chunked transfer encoding, cabeçalhos, redirecionamentos e TLS.
Visão Geral
const std = @import("std");
const http = std.http;
O módulo é dividido em:
http.Client— Para fazer requisições HTTPhttp.Server— Para servir requisições HTTPhttp.Method— Enum com métodos HTTPhttp.Status— Enum com códigos de statushttp.Header— Tipo para cabeçalhos
Tipos Principais
http.Method
pub const Method = enum {
GET,
HEAD,
POST,
PUT,
DELETE,
CONNECT,
OPTIONS,
TRACE,
PATCH,
// ...
};
http.Status
pub const Status = enum(u10) {
ok = 200,
created = 201,
no_content = 204,
moved_permanently = 301,
found = 302,
bad_request = 400,
unauthorized = 401,
forbidden = 403,
not_found = 404,
internal_server_error = 500,
// ...
pub fn phrase(self: Status) ?[]const u8
};
Funções Principais
Cliente
// Cria um cliente HTTP
pub fn Client.init(allocator: Allocator) Client
// Faz uma requisição
pub fn Client.fetch(self: *Client, options: FetchOptions) !FetchResult
// Libera recursos
pub fn Client.deinit(self: *Client) void
Servidor
// Cria servidor HTTP escutando em endereço
pub fn Server.init(config: Config) Server
// Aceita próxima requisição
pub fn Server.accept(self: *Server) !Request
// Para o servidor
pub fn Server.deinit(self: *Server) void
Exemplo 1: Requisição GET com Cliente HTTP
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Cria o cliente
var client = std.http.Client{ .allocator = allocator };
defer client.deinit();
// Buffer para o corpo da resposta
var body = std.ArrayList(u8).init(allocator);
defer body.deinit();
// Faz a requisição GET
const result = try client.fetch(.{
.location = .{ .url = "http://example.com/" },
.response_storage = .{ .dynamic = &body },
});
const stdout = std.io.getStdOut().writer();
try stdout.print("Status: {d} {s}\n", .{
@intFromEnum(result.status),
result.status.phrase() orelse "Desconhecido",
});
try stdout.print("Tamanho do corpo: {d} bytes\n", .{body.items.len});
// Mostra os primeiros 200 caracteres
const preview_len = @min(body.items.len, 200);
try stdout.print("Preview:\n{s}...\n", .{body.items[0..preview_len]});
}
Exemplo 2: Requisição POST com JSON
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var client = std.http.Client{ .allocator = allocator };
defer client.deinit();
const payload =
\\{"nome": "João", "email": "joao@exemplo.com"}
;
var body = std.ArrayList(u8).init(allocator);
defer body.deinit();
const result = try client.fetch(.{
.location = .{ .url = "https://httpbin.org/post" },
.method = .POST,
.headers = .{
.content_type = .{ .override = "application/json" },
},
.payload = payload,
.response_storage = .{ .dynamic = &body },
});
const stdout = std.io.getStdOut().writer();
try stdout.print("Status: {d}\n", .{@intFromEnum(result.status)});
try stdout.print("Resposta: {s}\n", .{body.items});
}
Exemplo 3: Servidor HTTP Simples
const std = @import("std");
const http = std.http;
const net = std.net;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const addr = try net.Address.parseIp4("127.0.0.1", 8080);
var server = try addr.listen(.{ .reuse_address = true });
defer server.deinit();
std.debug.print("Servidor HTTP em http://127.0.0.1:8080\n", .{});
while (true) {
var connection = try server.accept();
var buf: [4096]u8 = undefined;
var http_server = http.Server.init(connection, &buf);
var request = http_server.receiveHead() catch continue;
// Constrói resposta
const corpo = "Olá do servidor Zig!";
request.respond(corpo, .{
.extra_headers = &.{
.{ .name = "content-type", .value = "text/plain; charset=utf-8" },
},
}) catch continue;
std.debug.print("Requisição: {s} {s}\n", .{
@tagName(request.head.method),
request.head.target,
});
}
}
Códigos de Status Comuns
| Código | Constante | Significado |
|---|---|---|
| 200 | .ok | Sucesso |
| 201 | .created | Recurso criado |
| 301 | .moved_permanently | Redirecionamento permanente |
| 400 | .bad_request | Requisição inválida |
| 401 | .unauthorized | Não autenticado |
| 404 | .not_found | Não encontrado |
| 500 | .internal_server_error | Erro interno |
Módulos Relacionados
- std.http.Client — Detalhes do cliente HTTP
- std.http.Server — Detalhes do servidor HTTP
- std.net — Networking de baixo nível
- std.Uri — Parsing de URLs
- std.json — Serialização JSON para APIs