Status text constant and response builders

This commit is contained in:
2025-07-10 22:56:12 +02:00
parent af8bfe1518
commit 9998847c47

View File

@@ -4,23 +4,98 @@ const main = @import("main.zig");
threadlocal var read_buffer: [2 * 1024 * 1024]u8 = undefined; threadlocal var read_buffer: [2 * 1024 * 1024]u8 = undefined;
threadlocal var write_buffer: [2 * 1024 * 1024]u8 = undefined; threadlocal var write_buffer: [2 * 1024 * 1024]u8 = undefined;
const http_400 = "HTTP/1.1 400 Bad Request\r\n\r\n";
const http_404 = "HTTP/1.1 404 Not Found\r\n\r\n";
const http_413 = "HTTP/1.1 413 Content Too Large\r\n\r\n";
const http_431 = "HTTP/1.1 431 Request Header Fields Too Large\r\n\r\n";
const http_500 = "HTTP/1.1 500 Internal Server Error\r\n\r\n";
const log = std.log.scoped(.http); const log = std.log.scoped(.http);
fn http_200(content_type: []const u8, response_body: []const u8) ![]const u8 { const status = struct {
pub const ok = "HTTP/1.1 200 OK\r\n";
pub const created = "HTTP/1.1 201 Created\r\n";
pub const accepted = "HTTP/1.1 202 Accepted\r\n";
pub const non_authoritative_information = "HTTP/1.1 203 Non-Authoritative Information\r\n";
pub const no_content = "HTTP/1.1 204 No Content\r\n";
pub const reset_content = "HTTP/1.1 205 Reset Content\r\n";
pub const partial_content = "HTTP/1.1 206 Partial Content\r\n";
pub const multi_status = "HTTP/1.1 207 Multi-Status\r\n";
pub const already_reported = "HTTP/1.1 208 Already Reported\r\n";
pub const multiple_choices = "HTTP/1.1 300 Multiple Choices\r\n";
pub const moved_permanently = "HTTP/1.1 301 Moved Permanently\r\n";
pub const found = "HTTP/1.1 302 Found\r\n";
pub const see_other = "HTTP/1.1 303 See Other\r\n";
pub const not_modified = "HTTP/1.1 304 Not Modified\r\n";
pub const temporary_redirect = "HTTP/1.1 307 Temporary Redirect\r\n";
pub const permanent_redirect = "HTTP/1.1 308 Permanent Redirect\r\n";
pub const bad_request = "HTTP/1.1 400 Bad Request\r\n";
pub const unauthorized = "HTTP/1.1 401 Unauthorized\r\n";
pub const payment_required = "HTTP/1.1 402 Payment Required\r\n";
pub const forbidden = "HTTP/1.1 403 Forbidden\r\n";
pub const not_found = "HTTP/1.1 404 Not Found\r\n";
pub const method_not_allowed = "HTTP/1.1 405 Method Not Allowed\r\n";
pub const not_acceptable = "HTTP/1.1 406 Not Acceptable\r\n";
pub const proxy_authentication_required = "HTTP/1.1 407 Proxy Authentication Required\r\n";
pub const request_timeout = "HTTP/1.1 408 Request Timeout\r\n";
pub const conflict = "HTTP/1.1 409 Conflict\r\n";
pub const gone = "HTTP/1.1 410 Gone\r\n";
pub const length_required = "HTTP/1.1 411 Length Required\r\n";
pub const precondition_failed = "HTTP/1.1 412 Precondition Failed\r\n";
pub const content_too_large = "HTTP/1.1 413 Content Too Large\r\n";
pub const uri_too_long = "HTTP/1.1 414 URI Too Long\r\n";
pub const unsupported_media_type = "HTTP/1.1 415 Unsupported Media Type\r\n";
pub const range_not_satisfiable = "HTTP/1.1 416 Range Not Satisfiable\r\n";
pub const expectation_failed = "HTTP/1.1 417 Expectation Failed\r\n";
pub const im_a_teapot = "HTTP/1.1 418 I'm a teapot\r\n";
pub const misdirected_request = "HTTP/1.1 421 Misdirected Request\r\n";
pub const unprocessable_content = "HTTP/1.1 422 Unprocessable Content\r\n";
pub const locked = "HTTP/1.1 423 Locked\r\n";
pub const failed_dependency = "HTTP/1.1 424 Failed Dependency\r\n";
pub const upgrade_required = "HTTP/1.1 426 Upgrade Required\r\n";
pub const precondition_required = "HTTP/1.1 428 Precondition Required\r\n";
pub const too_many_requests = "HTTP/1.1 429 Too Many Requests\r\n";
pub const request_header_fields_too_large = "HTTP/1.1 431 Request Header Fields Too Large\r\n";
pub const unavailable_for_legal_reasons = "HTTP/1.1 451 Unavailable For Legal Reasons\r\n";
pub const internal_server_error = "HTTP/1.1 500 Internal Server Error\r\n";
pub const not_implemented = "HTTP/1.1 501 Not Implemented\r\n";
pub const bad_gateway = "HTTP/1.1 502 Bad Gateway\r\n";
pub const service_unavailable = "HTTP/1.1 503 Service Unavailable\r\n";
pub const gateway_timeout = "HTTP/1.1 504 Gateway Timeout\r\n";
pub const http_version_not_supported = "HTTP/1.1 505 HTTP Version Not Supported\r\n";
pub const variant_also_negotiates = "HTTP/1.1 506 Variant Also Negotiates\r\n";
pub const insufficient_storage = "HTTP/1.1 507 Insufficient Storage\r\n";
pub const loop_detected = "HTTP/1.1 508 Loop Detected\r\n";
pub const not_extended = "HTTP/1.1 510 Not Extended\r\n";
pub const network_authentication_required = "HTTP/1.1 511 Network Authentication Required\r\n";
};
const ResponseEmptyOptions = struct {
status_text: []const u8 = status.ok,
};
const ResponseOptions = struct {
status_text: []const u8 = status.ok,
media_type: []const u8 = "text/plain; charset=utf-8",
response_body: []const u8,
};
fn makeResponseEmpty(options: ResponseEmptyOptions) ![]const u8 {
var fbs = std.io.fixedBufferStream(&write_buffer); var fbs = std.io.fixedBufferStream(&write_buffer);
const writer = fbs.writer(); const writer = fbs.writer();
try writer.print("HTTP/1.1 200 OK\r\n", .{}); try writer.print("{s}", .{options.status_text});
try writer.print("Content-Type: {s}\r\n", .{content_type});
try writer.print("Content-Length: {d}\r\n", .{response_body.len});
try writer.print("\r\n", .{}); try writer.print("\r\n", .{});
try writer.print("{s}", .{response_body});
return fbs.getWritten();
}
fn makeResponse(options: ResponseOptions) ![]const u8 {
var fbs = std.io.fixedBufferStream(&write_buffer);
const writer = fbs.writer();
try writer.print("{s}", .{options.status_text});
try writer.print("Content-Type: {s}\r\n", .{options.media_type});
try writer.print("Content-Length: {d}\r\n", .{options.response_body.len});
try writer.print("\r\n", .{});
try writer.print("{s}", .{options.response_body});
return fbs.getWritten(); return fbs.getWritten();
} }
@@ -55,7 +130,9 @@ pub fn process(conn: std.net.Server.Connection) !void {
return err; return err;
}; };
const response = try http_200("text/plain; charset=utf-8", "PONG\n"); const response = try makeResponse(.{
.response_body = "PONG\n",
});
try conn.stream.writeAll(response); try conn.stream.writeAll(response);