diff --git a/packages/myid/src/http.zig b/packages/myid/src/http.zig index 01772d2..482f3ab 100644 --- a/packages/myid/src/http.zig +++ b/packages/myid/src/http.zig @@ -4,23 +4,98 @@ const main = @import("main.zig"); threadlocal var read_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); -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); const writer = fbs.writer(); - try writer.print("HTTP/1.1 200 OK\r\n", .{}); - try writer.print("Content-Type: {s}\r\n", .{content_type}); - try writer.print("Content-Length: {d}\r\n", .{response_body.len}); + try writer.print("{s}", .{options.status_text}); 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(); } @@ -55,7 +130,9 @@ pub fn process(conn: std.net.Server.Connection) !void { 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);