authorgravatar for truemedian@gmail.comNameless <truemedian@gmail.com> 2023-10-06 21:38:05-05:00
committergravatar for truemedian@gmail.comNameless <truemedian@gmail.com> 2023-10-21 20:52:59-05:00
logc523b5421be86cdd0591a5672eeaea30fb142fe4
tree17b23ca55286378604d878930523a32cf0fe796b
parent16f89eab45c4356f8f1d824c342e76aee8ddff90
signaturelock-open Commit is signed but in an unrecognized format.

std.http: make encoding fields non-null, store as enum variant


3 files changed, 52 insertions(+), 55 deletions(-)

lib/std/http.zig+3
......@@ -289,14 +289,17 @@ pub const Status = enum(u10) {
289289
290290pub const TransferEncoding = enum {
291291 chunked,
292 none,
292293 // compression is intentionally omitted here, as std.http.Client stores it as content-encoding
293294};
294295
295296pub const ContentEncoding = enum {
296297 identity,
297298 compress,
299 @"x-compress",
298300 deflate,
299301 gzip,
302 @"x-gzip",
300303 zstd,
301304};
302305
lib/std/http/Client.zig+24-27
......@@ -425,27 +425,23 @@ pub const Response = struct {
425425 // Transfer-Encoding: deflate, chunked
426426 var iter = mem.splitBackwardsScalar(u8, header_value, ',');
427427
428 if (iter.next()) |first| {
429 const trimmed = mem.trim(u8, first, " ");
430
431 if (std.meta.stringToEnum(http.TransferEncoding, trimmed)) |te| {
432 if (res.transfer_encoding != null) return error.HttpHeadersInvalid;
433 res.transfer_encoding = te;
434 } else if (std.meta.stringToEnum(http.ContentEncoding, trimmed)) |ce| {
435 if (res.transfer_compression != null) return error.HttpHeadersInvalid;
436 res.transfer_compression = ce;
437 } else {
438 return error.HttpTransferEncodingUnsupported;
439 }
440 }
428 const first = iter.first();
429 const trimmed_first = mem.trim(u8, first, " ");
441430
442 if (iter.next()) |second| {
443 if (res.transfer_compression != null) return error.HttpTransferEncodingUnsupported;
431 var next: ?[]const u8 = first;
432 if (std.meta.stringToEnum(http.TransferEncoding, trimmed_first)) |transfer| {
433 if (res.transfer_encoding != .none) return error.HttpHeadersInvalid; // we already have a transfer encoding
434 res.transfer_encoding = transfer;
444435
445 const trimmed = mem.trim(u8, second, " ");
436 next = iter.next();
437 }
438
439 if (next) |second| {
440 const trimmed_second = mem.trim(u8, second, " ");
446441
447 if (std.meta.stringToEnum(http.ContentEncoding, trimmed)) |ce| {
448 res.transfer_compression = ce;
442 if (std.meta.stringToEnum(http.ContentEncoding, trimmed_second)) |transfer| {
443 if (res.transfer_compression != .identity) return error.HttpHeadersInvalid; // double compression is not supported
444 res.transfer_compression = transfer;
449445 } else {
450446 return error.HttpTransferEncodingUnsupported;
451447 }
......@@ -459,7 +455,7 @@ pub const Response = struct {
459455
460456 res.content_length = content_length;
461457 } else if (std.ascii.eqlIgnoreCase(header_name, "content-encoding")) {
462 if (res.transfer_compression != null) return error.HttpHeadersInvalid;
458 if (res.transfer_compression != .identity) return error.HttpHeadersInvalid;
463459
464460 const trimmed = mem.trim(u8, header_value, " ");
465461
......@@ -494,8 +490,8 @@ pub const Response = struct {
494490 reason: []const u8,
495491
496492 content_length: ?u64 = null,
497 transfer_encoding: ?http.TransferEncoding = null,
498 transfer_compression: ?http.ContentEncoding = null,
493 transfer_encoding: http.TransferEncoding = .none,
494 transfer_compression: http.ContentEncoding = .identity,
499495
500496 headers: http.Headers,
501497 parser: proto.HeadersParser,
......@@ -771,8 +767,9 @@ pub const Request = struct {
771767 req.connection.?.closing = true;
772768 }
773769
774 if (req.response.transfer_encoding) |te| {
775 switch (te) {
770 if (req.response.transfer_encoding != .none) {
771 switch (req.response.transfer_encoding) {
772 .none => unreachable,
776773 .chunked => {
777774 req.response.parser.next_chunk_length = 0;
778775 req.response.parser.state = .chunk_head_size;
......@@ -840,19 +837,19 @@ pub const Request = struct {
840837 } else {
841838 req.response.skip = false;
842839 if (!req.response.parser.done) {
843 if (req.response.transfer_compression) |tc| switch (tc) {
840 switch (req.response.transfer_compression) {
844841 .identity => req.response.compression = .none,
845 .compress => return error.CompressionNotSupported,
842 .compress, .@"x-compress" => return error.CompressionNotSupported,
846843 .deflate => req.response.compression = .{
847844 .deflate = std.compress.zlib.decompressStream(req.client.allocator, req.transferReader()) catch return error.CompressionInitializationFailed,
848845 },
849 .gzip => req.response.compression = .{
846 .gzip, .@"x-gzip" => req.response.compression = .{
850847 .gzip = std.compress.gzip.decompress(req.client.allocator, req.transferReader()) catch return error.CompressionInitializationFailed,
851848 },
852849 .zstd => req.response.compression = .{
853850 .zstd = std.compress.zstd.decompressStream(req.client.allocator, req.transferReader()),
854851 },
855 };
852 }
856853 }
857854
858855 break;
lib/std/http/Server.zig+25-28
......@@ -228,27 +228,23 @@ pub const Request = struct {
228228 // Transfer-Encoding: deflate, chunked
229229 var iter = mem.splitBackwardsScalar(u8, header_value, ',');
230230
231 if (iter.next()) |first| {
232 const trimmed = mem.trim(u8, first, " ");
233
234 if (std.meta.stringToEnum(http.TransferEncoding, trimmed)) |te| {
235 if (req.transfer_encoding != null) return error.HttpHeadersInvalid;
236 req.transfer_encoding = te;
237 } else if (std.meta.stringToEnum(http.ContentEncoding, trimmed)) |ce| {
238 if (req.transfer_compression != null) return error.HttpHeadersInvalid;
239 req.transfer_compression = ce;
240 } else {
241 return error.HttpTransferEncodingUnsupported;
242 }
243 }
231 const first = iter.first();
232 const trimmed_first = mem.trim(u8, first, " ");
244233
245 if (iter.next()) |second| {
246 if (req.transfer_compression != null) return error.HttpTransferEncodingUnsupported;
234 var next: ?[]const u8 = first;
235 if (std.meta.stringToEnum(http.TransferEncoding, trimmed_first)) |transfer| {
236 if (req.transfer_encoding != .none) return error.HttpHeadersInvalid; // we already have a transfer encoding
237 req.transfer_encoding = transfer;
247238
248 const trimmed = mem.trim(u8, second, " ");
239 next = iter.next();
240 }
241
242 if (next) |second| {
243 const trimmed_second = mem.trim(u8, second, " ");
249244
250 if (std.meta.stringToEnum(http.ContentEncoding, trimmed)) |ce| {
251 req.transfer_compression = ce;
245 if (std.meta.stringToEnum(http.ContentEncoding, trimmed_second)) |transfer| {
246 if (req.transfer_compression != .identity) return error.HttpHeadersInvalid; // double compression is not supported
247 req.transfer_compression = transfer;
252248 } else {
253249 return error.HttpTransferEncodingUnsupported;
254250 }
......@@ -256,7 +252,7 @@ pub const Request = struct {
256252
257253 if (iter.next()) |_| return error.HttpTransferEncodingUnsupported;
258254 } else if (std.ascii.eqlIgnoreCase(header_name, "content-encoding")) {
259 if (req.transfer_compression != null) return error.HttpHeadersInvalid;
255 if (req.transfer_compression != .identity) return error.HttpHeadersInvalid;
260256
261257 const trimmed = mem.trim(u8, header_value, " ");
262258
......@@ -278,8 +274,8 @@ pub const Request = struct {
278274 version: http.Version,
279275
280276 content_length: ?u64 = null,
281 transfer_encoding: ?http.TransferEncoding = null,
282 transfer_compression: ?http.ContentEncoding = null,
277 transfer_encoding: http.TransferEncoding = .none,
278 transfer_compression: http.ContentEncoding = .identity,
283279
284280 headers: http.Headers,
285281 parser: proto.HeadersParser,
......@@ -511,8 +507,9 @@ pub const Response = struct {
511507 res.request.headers = .{ .allocator = res.allocator, .owned = true };
512508 try res.request.parse(res.request.parser.header_bytes.items);
513509
514 if (res.request.transfer_encoding) |te| {
515 switch (te) {
510 if (res.request.transfer_encoding != .none) {
511 switch (res.request.transfer_encoding) {
512 .none => unreachable,
516513 .chunked => {
517514 res.request.parser.next_chunk_length = 0;
518515 res.request.parser.state = .chunk_head_size;
......@@ -527,19 +524,19 @@ pub const Response = struct {
527524 }
528525
529526 if (!res.request.parser.done) {
530 if (res.request.transfer_compression) |tc| switch (tc) {
527 switch (res.request.transfer_compression) {
531528 .identity => res.request.compression = .none,
532 .compress => return error.CompressionNotSupported,
529 .compress, .@"x-compress" => return error.CompressionNotSupported,
533530 .deflate => res.request.compression = .{
534531 .deflate = std.compress.zlib.decompressStream(res.allocator, res.transferReader()) catch return error.CompressionInitializationFailed,
535532 },
536 .gzip => res.request.compression = .{
533 .gzip, .@"x-gzip" => res.request.compression = .{
537534 .gzip = std.compress.gzip.decompress(res.allocator, res.transferReader()) catch return error.CompressionInitializationFailed,
538535 },
539536 .zstd => res.request.compression = .{
540537 .zstd = std.compress.zstd.decompressStream(res.allocator, res.transferReader()),
541538 },
542 };
539 }
543540 }
544541 }
545542
......@@ -754,7 +751,7 @@ test "HTTP server handles a chunked transfer coding request" {
754751 defer _ = res.reset();
755752 try res.wait();
756753
757 try expect(res.request.transfer_encoding.? == .chunked);
754 try expect(res.request.transfer_encoding == .chunked);
758755
759756 const server_body: []const u8 = "message from server!\n";
760757 res.transfer_encoding = .{ .content_length = server_body.len };