@@ -37,8 +37,6 @@ const BUFFER_LEN = 32 * 1024;
3737// The longest individual header line that we support
3838const MAX_HEADER_LINE_LEN = 4096 ;
3939
40- const HeaderList = std .ArrayListUnmanaged (std .http .Header );
41-
4240// Thread-safe. Holds our root certificate, connection pool and state pool
4341// Used to create Requests.
4442pub const Client = struct {
@@ -114,7 +112,7 @@ pub const Request = struct {
114112 arena : Allocator ,
115113
116114 // List of request headers
117- headers : HeaderList ,
115+ headers : std . ArrayListUnmanaged ( std . http . Header ) ,
118116
119117 // Used to limit the # of redirects we'll follow
120118 _redirect_count : u16 ,
@@ -1438,10 +1436,11 @@ const Reader = struct {
14381436pub const ResponseHeader = struct {
14391437 status : u16 = 0 ,
14401438 keepalive : bool = false ,
1441- headers : HeaderList = .{},
1439+ headers : std . ArrayListUnmanaged ( Header ) = .{},
14421440
1443- // Stored header has already been lower-cased, we expect name to be lowercased
1444- pub fn get (self : * const ResponseHeader , name : []const u8 ) ? []const u8 {
1441+ // Stored header has already been lower-cased
1442+ // `name` parameter should be passed in lower-cased
1443+ pub fn get (self : * const ResponseHeader , name : []const u8 ) ? []u8 {
14451444 for (self .headers .items ) | h | {
14461445 if (std .mem .eql (u8 , name , h .name )) {
14471446 return h .value ;
@@ -1463,12 +1462,23 @@ pub const ResponseHeader = struct {
14631462 }
14641463};
14651464
1465+ // We don't want to use std.http.Header, because the value is `[]const u8`.
1466+ // We _could_ use it and @constCast, but this gives us more safety.
1467+ // The main reason we want to do this is that a caller could lower-case the
1468+ // value in-place.
1469+ // The value (and key) are both safe to mutate because they're cloned from
1470+ // the byte stream by our arena.
1471+ const Header = struct {
1472+ name : []const u8 ,
1473+ value : []u8 ,
1474+ };
1475+
14661476const HeaderIterator = struct {
14671477 index : usize ,
14681478 name : []const u8 ,
1469- headers : HeaderList ,
1479+ headers : std . ArrayListUnmanaged ( Header ) ,
14701480
1471- pub fn next (self : * HeaderIterator ) ? []const u8 {
1481+ pub fn next (self : * HeaderIterator ) ? []u8 {
14721482 const name = self .name ;
14731483 const index = self .index ;
14741484 for (self .headers .items [index .. ], index .. ) | h , i | {
@@ -2108,11 +2118,13 @@ test "HttpClient: HeaderIterator" {
21082118 try testing .expectEqual (null , it .next ());
21092119 }
21102120
2111- try header .headers .append (testing .allocator , .{ .name = "h1" , .value = "value1" });
2112- try header .headers .append (testing .allocator , .{ .name = "h2" , .value = "value2" });
2113- try header .headers .append (testing .allocator , .{ .name = "h3" , .value = "value3" });
2114- try header .headers .append (testing .allocator , .{ .name = "h1" , .value = "value4" });
2115- try header .headers .append (testing .allocator , .{ .name = "h1" , .value = "value5" });
2121+ // @constCast is totally unsafe here, but it's just a test, and we know
2122+ // nothing is going to write to it, so it works.
2123+ try header .headers .append (testing .allocator , .{ .name = "h1" , .value = @constCast ("value1" ) });
2124+ try header .headers .append (testing .allocator , .{ .name = "h2" , .value = @constCast ("value2" ) });
2125+ try header .headers .append (testing .allocator , .{ .name = "h3" , .value = @constCast ("value3" ) });
2126+ try header .headers .append (testing .allocator , .{ .name = "h1" , .value = @constCast ("value4" ) });
2127+ try header .headers .append (testing .allocator , .{ .name = "h1" , .value = @constCast ("value5" ) });
21162128
21172129 {
21182130 var it = header .iterate ("nope" );
@@ -2149,7 +2161,7 @@ const TestResponse = struct {
21492161 keepalive : ? bool ,
21502162 arena : std.heap.ArenaAllocator ,
21512163 body : std .ArrayListUnmanaged (u8 ),
2152- headers : std .ArrayListUnmanaged (std . http . Header ),
2164+ headers : std .ArrayListUnmanaged (Header ),
21532165
21542166 fn init () TestResponse {
21552167 return .{
0 commit comments