Commit c523b5421b
Changed files (3)
lib
std
lib/std/http/Client.zig
@@ -425,27 +425,23 @@ pub const Response = struct {
// Transfer-Encoding: deflate, chunked
var iter = mem.splitBackwardsScalar(u8, header_value, ',');
- if (iter.next()) |first| {
- const trimmed = mem.trim(u8, first, " ");
-
- if (std.meta.stringToEnum(http.TransferEncoding, trimmed)) |te| {
- if (res.transfer_encoding != null) return error.HttpHeadersInvalid;
- res.transfer_encoding = te;
- } else if (std.meta.stringToEnum(http.ContentEncoding, trimmed)) |ce| {
- if (res.transfer_compression != null) return error.HttpHeadersInvalid;
- res.transfer_compression = ce;
- } else {
- return error.HttpTransferEncodingUnsupported;
- }
- }
+ const first = iter.first();
+ const trimmed_first = mem.trim(u8, first, " ");
- if (iter.next()) |second| {
- if (res.transfer_compression != null) return error.HttpTransferEncodingUnsupported;
+ var next: ?[]const u8 = first;
+ if (std.meta.stringToEnum(http.TransferEncoding, trimmed_first)) |transfer| {
+ if (res.transfer_encoding != .none) return error.HttpHeadersInvalid; // we already have a transfer encoding
+ res.transfer_encoding = transfer;
- const trimmed = mem.trim(u8, second, " ");
+ next = iter.next();
+ }
+
+ if (next) |second| {
+ const trimmed_second = mem.trim(u8, second, " ");
- if (std.meta.stringToEnum(http.ContentEncoding, trimmed)) |ce| {
- res.transfer_compression = ce;
+ if (std.meta.stringToEnum(http.ContentEncoding, trimmed_second)) |transfer| {
+ if (res.transfer_compression != .identity) return error.HttpHeadersInvalid; // double compression is not supported
+ res.transfer_compression = transfer;
} else {
return error.HttpTransferEncodingUnsupported;
}
@@ -459,7 +455,7 @@ pub const Response = struct {
res.content_length = content_length;
} else if (std.ascii.eqlIgnoreCase(header_name, "content-encoding")) {
- if (res.transfer_compression != null) return error.HttpHeadersInvalid;
+ if (res.transfer_compression != .identity) return error.HttpHeadersInvalid;
const trimmed = mem.trim(u8, header_value, " ");
@@ -494,8 +490,8 @@ pub const Response = struct {
reason: []const u8,
content_length: ?u64 = null,
- transfer_encoding: ?http.TransferEncoding = null,
- transfer_compression: ?http.ContentEncoding = null,
+ transfer_encoding: http.TransferEncoding = .none,
+ transfer_compression: http.ContentEncoding = .identity,
headers: http.Headers,
parser: proto.HeadersParser,
@@ -771,8 +767,9 @@ pub const Request = struct {
req.connection.?.closing = true;
}
- if (req.response.transfer_encoding) |te| {
- switch (te) {
+ if (req.response.transfer_encoding != .none) {
+ switch (req.response.transfer_encoding) {
+ .none => unreachable,
.chunked => {
req.response.parser.next_chunk_length = 0;
req.response.parser.state = .chunk_head_size;
@@ -840,19 +837,19 @@ pub const Request = struct {
} else {
req.response.skip = false;
if (!req.response.parser.done) {
- if (req.response.transfer_compression) |tc| switch (tc) {
+ switch (req.response.transfer_compression) {
.identity => req.response.compression = .none,
- .compress => return error.CompressionNotSupported,
+ .compress, .@"x-compress" => return error.CompressionNotSupported,
.deflate => req.response.compression = .{
.deflate = std.compress.zlib.decompressStream(req.client.allocator, req.transferReader()) catch return error.CompressionInitializationFailed,
},
- .gzip => req.response.compression = .{
+ .gzip, .@"x-gzip" => req.response.compression = .{
.gzip = std.compress.gzip.decompress(req.client.allocator, req.transferReader()) catch return error.CompressionInitializationFailed,
},
.zstd => req.response.compression = .{
.zstd = std.compress.zstd.decompressStream(req.client.allocator, req.transferReader()),
},
- };
+ }
}
break;
lib/std/http/Server.zig
@@ -228,27 +228,23 @@ pub const Request = struct {
// Transfer-Encoding: deflate, chunked
var iter = mem.splitBackwardsScalar(u8, header_value, ',');
- if (iter.next()) |first| {
- const trimmed = mem.trim(u8, first, " ");
-
- if (std.meta.stringToEnum(http.TransferEncoding, trimmed)) |te| {
- if (req.transfer_encoding != null) return error.HttpHeadersInvalid;
- req.transfer_encoding = te;
- } else if (std.meta.stringToEnum(http.ContentEncoding, trimmed)) |ce| {
- if (req.transfer_compression != null) return error.HttpHeadersInvalid;
- req.transfer_compression = ce;
- } else {
- return error.HttpTransferEncodingUnsupported;
- }
- }
+ const first = iter.first();
+ const trimmed_first = mem.trim(u8, first, " ");
- if (iter.next()) |second| {
- if (req.transfer_compression != null) return error.HttpTransferEncodingUnsupported;
+ var next: ?[]const u8 = first;
+ if (std.meta.stringToEnum(http.TransferEncoding, trimmed_first)) |transfer| {
+ if (req.transfer_encoding != .none) return error.HttpHeadersInvalid; // we already have a transfer encoding
+ req.transfer_encoding = transfer;
- const trimmed = mem.trim(u8, second, " ");
+ next = iter.next();
+ }
+
+ if (next) |second| {
+ const trimmed_second = mem.trim(u8, second, " ");
- if (std.meta.stringToEnum(http.ContentEncoding, trimmed)) |ce| {
- req.transfer_compression = ce;
+ if (std.meta.stringToEnum(http.ContentEncoding, trimmed_second)) |transfer| {
+ if (req.transfer_compression != .identity) return error.HttpHeadersInvalid; // double compression is not supported
+ req.transfer_compression = transfer;
} else {
return error.HttpTransferEncodingUnsupported;
}
@@ -256,7 +252,7 @@ pub const Request = struct {
if (iter.next()) |_| return error.HttpTransferEncodingUnsupported;
} else if (std.ascii.eqlIgnoreCase(header_name, "content-encoding")) {
- if (req.transfer_compression != null) return error.HttpHeadersInvalid;
+ if (req.transfer_compression != .identity) return error.HttpHeadersInvalid;
const trimmed = mem.trim(u8, header_value, " ");
@@ -278,8 +274,8 @@ pub const Request = struct {
version: http.Version,
content_length: ?u64 = null,
- transfer_encoding: ?http.TransferEncoding = null,
- transfer_compression: ?http.ContentEncoding = null,
+ transfer_encoding: http.TransferEncoding = .none,
+ transfer_compression: http.ContentEncoding = .identity,
headers: http.Headers,
parser: proto.HeadersParser,
@@ -511,8 +507,9 @@ pub const Response = struct {
res.request.headers = .{ .allocator = res.allocator, .owned = true };
try res.request.parse(res.request.parser.header_bytes.items);
- if (res.request.transfer_encoding) |te| {
- switch (te) {
+ if (res.request.transfer_encoding != .none) {
+ switch (res.request.transfer_encoding) {
+ .none => unreachable,
.chunked => {
res.request.parser.next_chunk_length = 0;
res.request.parser.state = .chunk_head_size;
@@ -527,19 +524,19 @@ pub const Response = struct {
}
if (!res.request.parser.done) {
- if (res.request.transfer_compression) |tc| switch (tc) {
+ switch (res.request.transfer_compression) {
.identity => res.request.compression = .none,
- .compress => return error.CompressionNotSupported,
+ .compress, .@"x-compress" => return error.CompressionNotSupported,
.deflate => res.request.compression = .{
.deflate = std.compress.zlib.decompressStream(res.allocator, res.transferReader()) catch return error.CompressionInitializationFailed,
},
- .gzip => res.request.compression = .{
+ .gzip, .@"x-gzip" => res.request.compression = .{
.gzip = std.compress.gzip.decompress(res.allocator, res.transferReader()) catch return error.CompressionInitializationFailed,
},
.zstd => res.request.compression = .{
.zstd = std.compress.zstd.decompressStream(res.allocator, res.transferReader()),
},
- };
+ }
}
}
@@ -754,7 +751,7 @@ test "HTTP server handles a chunked transfer coding request" {
defer _ = res.reset();
try res.wait();
- try expect(res.request.transfer_encoding.? == .chunked);
+ try expect(res.request.transfer_encoding == .chunked);
const server_body: []const u8 = "message from server!\n";
res.transfer_encoding = .{ .content_length = server_body.len };
lib/std/http.zig
@@ -289,14 +289,17 @@ pub const Status = enum(u10) {
pub const TransferEncoding = enum {
chunked,
+ none,
// compression is intentionally omitted here, as std.http.Client stores it as content-encoding
};
pub const ContentEncoding = enum {
identity,
compress,
+ @"x-compress",
deflate,
gzip,
+ @"x-gzip",
zstd,
};