diff --git a/examples/serve/serve.zig b/examples/serve/serve.zig index 2ff2862..c891fe7 100644 --- a/examples/serve/serve.zig +++ b/examples/serve/serve.zig @@ -2,7 +2,7 @@ const std = @import("std"); const zap = @import("zap"); fn on_request(r: zap.SimpleRequest) void { - r.setStatus(404); + r.setStatus(.not_found); _ = r.sendBody("

404 - File not found

"); } diff --git a/src/http.zig b/src/http.zig new file mode 100644 index 0000000..4978490 --- /dev/null +++ b/src/http.zig @@ -0,0 +1,107 @@ +/// HTTP Status codes according to `rfc7231` +/// https://tools.ietf.org/html/rfc7231#section-6 +/// (taken from https://github.com/Luukdegram/apple_pie/blob/master/src/response.zig) +pub const StatusCode = enum(u16) { + // Informational 1xx + @"continue" = 100, + // Successful 2xx + switching_protocols = 101, + ok = 200, + created = 201, + accepted = 202, + non_authoritative_information = 203, + no_content = 204, + reset_content = 205, + // redirections 3xx + partial_content = 206, + multiple_choices = 300, + moved_permanently = 301, + found = 302, + see_other = 303, + not_modified = 304, + use_proxy = 305, + temporary_redirect = 307, + // client errors 4xx + bad_request = 400, + unauthorized = 401, + payment_required = 402, + forbidden = 403, + not_found = 404, + method_not_allowed = 405, + not_acceptable = 406, + proxy_authentication_required = 407, + request_timeout = 408, + conflict = 409, + gone = 410, + length_required = 411, + precondition_failed = 412, + request_entity_too_large = 413, + request_uri_too_long = 414, + unsupported_mediatype = 415, + requested_range_not_satisfiable = 416, + expectation_failed = 417, + /// teapot is an extension status code and not required for clients to support + teapot = 418, + upgrade_required = 426, + /// extra status code according to `https://tools.ietf.org/html/rfc6585#section-5` + request_header_fields_too_large = 431, + // server errors 5xx + internal_server_error = 500, + not_implemented = 501, + bad_gateway = 502, + service_unavailable = 503, + gateway_timeout = 504, + http_version_not_supported = 505, + _, + + /// Returns the string value of a `StatusCode` + /// for example: .ResetContent returns "Returns Content". + pub fn toString(self: StatusCode) []const u8 { + return switch (self) { + .@"continue" => "Continue", + .switching_protocols => "Switching Protocols", + .ok => "Ok", + .created => "Created", + .accepted => "Accepted", + .non_authoritative_information => "Non Authoritative Information", + .no_content => "No Content", + .reset_content => "Reset Content", + .partial_content => "Partial Content", + .multiple_choices => "Multiple Choices", + .moved_permanently => "Moved Permanently", + .found => "Found", + .see_other => "See Other", + .not_modified => "Not Modified", + .use_proxy => "Use Proxy", + .temporary_redirect => "Temporary Redirect", + .bad_request => "Bad Request", + .unauthorized => "Unauthorized", + .payment_required => "Payment Required", + .forbidden => "Forbidden", + .not_found => "Not Found", + .method_not_allowed => "Method Not Allowed", + .not_acceptable => "Not Acceptable", + .proxy_authentication_required => "Proxy Authentication Required", + .request_timeout => "Request Timeout", + .conflict => "Conflict", + .gone => "Gone", + .length_required => "Length Required", + .precondition_failed => "Precondition Failed", + .request_entity_too_large => "Request Entity Too Large", + .request_uri_too_long => "Request-URI Too Long", + .unsupported_mediatype => "Unsupported Media Type", + .requested_range_not_satisfiable => "Requested Range Not Satisfiable", + .teapot => "I'm a Teapot", + .upgrade_required => "Upgrade Required", + .request_header_fields_too_large => "Request Header Fields Too Large", + .expectation_failed => "Expectation Failed", + .internal_server_error => "Internal Server Error", + .not_implemented => "Not Implemented", + .bad_gateway => "Bad Gateway", + .service_unavailable => "Service Unavailable", + .gateway_timeout => "Gateway Timeout", + .http_version_not_supported => "HTTP Version Not Supported", + _ => "", + }; + } +}; diff --git a/src/zap.zig b/src/zap.zig index 0639b5a..5c0ab95 100644 --- a/src/zap.zig +++ b/src/zap.zig @@ -9,6 +9,9 @@ pub const C = @cImport({ pub usingnamespace @import("endpoint.zig"); pub usingnamespace @import("util.zig"); +pub usingnamespace @import("http.zig"); + +const _module = @This(); pub fn fio2str(o: C.FIOBJ) ?[]const u8 { if (o == 0) return null; @@ -98,10 +101,14 @@ pub const SimpleRequest = struct { // C.fiobj_free(new_fiobj_str); } - pub fn setStatus(self: *const Self, status: usize) void { + pub fn setStatusNumeric(self: *const Self, status: usize) void { self.h.*.status = status; } + pub fn setStatus(self: *const Self, status: _module.StatusCode) void { + self.h.*.status = @intCast(usize, @enumToInt(status)); + } + pub fn nextParam(self: *const Self) ?HttpParam { if (self.h.*.params == 0) return null; var key: C.FIOBJ = undefined;