authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-08-06 19:56:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-08-06 22:42:43-07:00
log2c82d1c03aaa2c2abce3d620ae831ac31cf58e2c
tree0f85653e2e1df0b10815dc0cc30be449a6c93420
parent1596aed1fd1306b99a1da417d10e79cf53aa05ab

std.http: remove custom method support

let's see if anybody notices it missing

4 files changed, 24 insertions(+), 47 deletions(-)

lib/std/http.zig+20-42
......@@ -20,51 +20,32 @@ pub const Version = enum {
2020/// https://datatracker.ietf.org/doc/html/rfc7231#section-4 Initial definition
2121///
2222/// https://datatracker.ietf.org/doc/html/rfc5789#section-2 PATCH
23pub const Method = enum(u64) {
24 GET = parse("GET"),
25 HEAD = parse("HEAD"),
26 POST = parse("POST"),
27 PUT = parse("PUT"),
28 DELETE = parse("DELETE"),
29 CONNECT = parse("CONNECT"),
30 OPTIONS = parse("OPTIONS"),
31 TRACE = parse("TRACE"),
32 PATCH = parse("PATCH"),
33
34 _,
35
36 /// Converts `s` into a type that may be used as a `Method` field.
37 /// Asserts that `s` is 24 or fewer bytes.
38 pub fn parse(s: []const u8) u64 {
39 var x: u64 = 0;
40 const len = @min(s.len, @sizeOf(@TypeOf(x)));
41 @memcpy(std.mem.asBytes(&x)[0..len], s[0..len]);
42 return x;
43 }
44
45 pub fn format(self: Method, w: *Writer) Writer.Error!void {
46 const bytes: []const u8 = @ptrCast(&@intFromEnum(self));
47 const str = std.mem.sliceTo(bytes, 0);
48 try w.writeAll(str);
49 }
23pub const Method = enum {
24 GET,
25 HEAD,
26 POST,
27 PUT,
28 DELETE,
29 CONNECT,
30 OPTIONS,
31 TRACE,
32 PATCH,
5033
5134 /// Returns true if a request of this method is allowed to have a body
5235 /// Actual behavior from servers may vary and should still be checked
53 pub fn requestHasBody(self: Method) bool {
54 return switch (self) {
36 pub fn requestHasBody(m: Method) bool {
37 return switch (m) {
5538 .POST, .PUT, .PATCH => true,
5639 .GET, .HEAD, .DELETE, .CONNECT, .OPTIONS, .TRACE => false,
57 else => true,
5840 };
5941 }
6042
6143 /// Returns true if a response to this method is allowed to have a body
6244 /// Actual behavior from clients may vary and should still be checked
63 pub fn responseHasBody(self: Method) bool {
64 return switch (self) {
45 pub fn responseHasBody(m: Method) bool {
46 return switch (m) {
6547 .GET, .POST, .DELETE, .CONNECT, .OPTIONS, .PATCH => true,
6648 .HEAD, .PUT, .TRACE => false,
67 else => true,
6849 };
6950 }
7051
......@@ -73,11 +54,10 @@ pub const Method = enum(u64) {
7354 /// https://developer.mozilla.org/en-US/docs/Glossary/Safe/HTTP
7455 ///
7556 /// https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.1
76 pub fn safe(self: Method) bool {
77 return switch (self) {
57 pub fn safe(m: Method) bool {
58 return switch (m) {
7859 .GET, .HEAD, .OPTIONS, .TRACE => true,
7960 .POST, .PUT, .DELETE, .CONNECT, .PATCH => false,
80 else => false,
8161 };
8262 }
8363
......@@ -88,11 +68,10 @@ pub const Method = enum(u64) {
8868 /// https://developer.mozilla.org/en-US/docs/Glossary/Idempotent
8969 ///
9070 /// https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.2
91 pub fn idempotent(self: Method) bool {
92 return switch (self) {
71 pub fn idempotent(m: Method) bool {
72 return switch (m) {
9373 .GET, .HEAD, .PUT, .DELETE, .OPTIONS, .TRACE => true,
9474 .CONNECT, .POST, .PATCH => false,
95 else => false,
9675 };
9776 }
9877
......@@ -102,11 +81,10 @@ pub const Method = enum(u64) {
10281 /// https://developer.mozilla.org/en-US/docs/Glossary/cacheable
10382 ///
10483 /// https://datatracker.ietf.org/doc/html/rfc7231#section-4.2.3
105 pub fn cacheable(self: Method) bool {
106 return switch (self) {
84 pub fn cacheable(m: Method) bool {
85 return switch (m) {
10786 .GET, .HEAD => true,
10887 .POST, .PUT, .DELETE, .CONNECT, .OPTIONS, .TRACE, .PATCH => false,
109 else => false,
11088 };
11189 }
11290};
lib/std/http/Client.zig+1-1
......@@ -928,7 +928,7 @@ pub const Request = struct {
928928 const connection = r.connection.?;
929929 const w = connection.writer();
930930
931 try r.method.format(w);
931 try w.writeAll(@tagName(r.method));
932932 try w.writeByte(' ');
933933
934934 if (r.method == .CONNECT) {
lib/std/http/Server.zig+2-3
......@@ -97,10 +97,9 @@ pub const Request = struct {
9797
9898 const method_end = mem.indexOfScalar(u8, first_line, ' ') orelse
9999 return error.HttpHeadersInvalid;
100 if (method_end > 24) return error.HttpHeadersInvalid;
101100
102 const method_str = first_line[0..method_end];
103 const method: http.Method = @enumFromInt(http.Method.parse(method_str));
101 const method = std.meta.stringToEnum(http.Method, first_line[0..method_end]) orelse
102 return error.UnknownHttpMethod;
104103
105104 const version_start = mem.lastIndexOfScalar(u8, first_line, ' ') orelse
106105 return error.HttpHeadersInvalid;
lib/std/http/test.zig+1-1
......@@ -413,7 +413,7 @@ test "general client/server API coverage" {
413413 const log = std.log.scoped(.server);
414414 const gpa = std.testing.allocator;
415415
416 log.info("{f} {t} {s}", .{ request.head.method, request.head.version, request.head.target });
416 log.info("{t} {t} {s}", .{ request.head.method, request.head.version, request.head.target });
417417 const target = try gpa.dupe(u8, request.head.target);
418418 defer gpa.free(target);
419419