@@ -63,9 +63,10 @@ headers: HeaderHashMap = .empty,
6363pub const HeadersInit = union (enum ) {
6464 // List of Pairs of []const u8
6565 strings : []const [2 ][]const u8 ,
66- // Mappings
67- mappings : Env.JsObject ,
66+ // Headers
6867 headers : * Headers ,
68+ // Mappings
69+ object : Env.JsObject ,
6970};
7071
7172pub fn constructor (_init : ? HeadersInit , page : * Page ) ! Headers {
@@ -82,27 +83,22 @@ pub fn constructor(_init: ?HeadersInit, page: *Page) !Headers {
8283 try headers .put (arena , key , value );
8384 }
8485 },
85- .mappings = > | obj | {
86+ .headers = > | hdrs | {
87+ var iter = hdrs .headers .iterator ();
88+ while (iter .next ()) | entry | {
89+ try headers .put (arena , entry .key_ptr .* , entry .value_ptr .* );
90+ }
91+ },
92+ .object = > | obj | {
8693 var iter = obj .nameIterator ();
8794 while (try iter .next ()) | name_value | {
8895 const name = try name_value .toString (arena );
89- const value = Env.Value {
90- .js_context = page .main_context ,
91- .value = name_value .value ,
92- };
96+ const value = try obj .get (name );
9397 const value_string = try value .toString (arena );
9498
9599 try headers .put (arena , name , value_string );
96100 }
97101 },
98- .headers = > | hdrs | {
99- var iter = hdrs .headers .iterator ();
100- while (iter .next ()) | entry | {
101- const key = try arena .dupe (u8 , entry .key_ptr .* );
102- const value = try arena .dupe (u8 , entry .value_ptr .* );
103- try headers .put (arena , key , value );
104- }
105- },
106102 }
107103 }
108104
@@ -140,12 +136,12 @@ pub fn _delete(self: *Headers, name: []const u8) void {
140136}
141137
142138pub const HeaderEntryIterator = struct {
143- slot : [][]const u8 ,
139+ slot : [2 ][]const u8 ,
144140 iter : HeaderHashMap.Iterator ,
145141
146142 // TODO: these SHOULD be in lexigraphical order but I'm not sure how actually
147143 // important that is.
148- pub fn _next (self : * HeaderEntryIterator ) ? [] const []const u8 {
144+ pub fn _next (self : * HeaderEntryIterator ) ? [2 ] []const u8 {
149145 if (self .iter .next ()) | entry | {
150146 self .slot [0 ] = entry .key_ptr .* ;
151147 self .slot [1 ] = entry .value_ptr .* ;
@@ -156,31 +152,20 @@ pub const HeaderEntryIterator = struct {
156152 }
157153};
158154
159- pub fn _entries (self : * const Headers , page : * Page ) ! HeaderEntryIterator {
155+ pub fn _entries (self : * const Headers ) HeaderEntryIterator {
160156 return .{
161- .slot = try page . arena . alloc ([] const u8 , 2 ) ,
157+ .slot = undefined ,
162158 .iter = self .headers .iterator (),
163159 };
164160}
165161
166162pub fn _forEach (self : * Headers , callback_fn : Env.Function , this_arg : ? Env.JsObject ) ! void {
167163 var iter = self .headers .iterator ();
168164
169- if (this_arg ) | this | {
170- while (iter .next ()) | entry | {
171- try callback_fn .callWithThis (
172- void ,
173- this ,
174- .{ entry .key_ptr .* , entry .value_ptr .* , self },
175- );
176- }
177- } else {
178- while (iter .next ()) | entry | {
179- try callback_fn .call (
180- void ,
181- .{ entry .key_ptr .* , entry .value_ptr .* , self },
182- );
183- }
165+ const cb = if (this_arg ) | this | try callback_fn .withThis (this ) else callback_fn ;
166+
167+ while (iter .next ()) | entry | {
168+ try cb .call (void , .{ entry .key_ptr .* , entry .value_ptr .* , self });
184169 }
185170}
186171
@@ -195,7 +180,7 @@ pub fn _has(self: *const Headers, name: []const u8) bool {
195180pub const HeaderKeyIterator = struct {
196181 iter : HeaderHashMap.KeyIterator ,
197182
198- pub fn _next (self : * HeaderKeyIterator ) ! ? []const u8 {
183+ pub fn _next (self : * HeaderKeyIterator ) ? []const u8 {
199184 if (self .iter .next ()) | key | {
200185 return key .* ;
201186 } else {
@@ -204,7 +189,7 @@ pub const HeaderKeyIterator = struct {
204189 }
205190};
206191
207- pub fn _keys (self : * const Headers , _ : * Page ) HeaderKeyIterator {
192+ pub fn _keys (self : * const Headers ) HeaderKeyIterator {
208193 return .{ .iter = self .headers .keyIterator () };
209194}
210195
@@ -218,7 +203,7 @@ pub fn _set(self: *Headers, name: []const u8, value: []const u8, page: *Page) !v
218203pub const HeaderValueIterator = struct {
219204 iter : HeaderHashMap.ValueIterator ,
220205
221- pub fn _next (self : * HeaderValueIterator ) ! ? []const u8 {
206+ pub fn _next (self : * HeaderValueIterator ) ? []const u8 {
222207 if (self .iter .next ()) | value | {
223208 return value .* ;
224209 } else {
@@ -227,7 +212,7 @@ pub const HeaderValueIterator = struct {
227212 }
228213};
229214
230- pub fn _values (self : * const Headers , _ : * Page ) HeaderValueIterator {
215+ pub fn _values (self : * const Headers ) HeaderValueIterator {
231216 return .{ .iter = self .headers .valueIterator () };
232217}
233218
@@ -237,11 +222,11 @@ test "fetch: headers" {
237222 defer runner .deinit ();
238223
239224 try runner .testCases (&.{
240- .{ "let empty_headers = new Headers()" , "undefined" },
225+ .{ "let emptyHeaders = new Headers()" , "undefined" },
241226 }, .{});
242227
243228 try runner .testCases (&.{
244- .{ "let headers = new Headers([[ 'Set-Cookie', 'name=world']] )" , "undefined" },
229+ .{ "let headers = new Headers({ 'Set-Cookie': 'name=world'} )" , "undefined" },
245230 .{ "headers.get('set-cookie')" , "name=world" },
246231 }, .{});
247232
@@ -259,4 +244,21 @@ test "fetch: headers" {
259244 .{ "myHeaders.get('Picture-Type')" , "image/svg" },
260245 .{ "myHeaders.has('Picture-Type')" , "true" },
261246 }, .{});
247+
248+ try runner .testCases (&.{
249+ .{ "const originalHeaders = new Headers([['Content-Type', 'application/json'], ['Authorization', 'Bearer token123']])" , "undefined" },
250+ .{ "originalHeaders.get('Content-Type')" , "application/json" },
251+ .{ "originalHeaders.get('Authorization')" , "Bearer token123" },
252+ .{ "const newHeaders = new Headers(originalHeaders)" , "undefined" },
253+ .{ "newHeaders.get('Content-Type')" , "application/json" },
254+ .{ "newHeaders.get('Authorization')" , "Bearer token123" },
255+ .{ "newHeaders.has('Content-Type')" , "true" },
256+ .{ "newHeaders.has('Authorization')" , "true" },
257+ .{ "newHeaders.has('X-Custom')" , "false" },
258+ // Verify that modifying the new headers doesn't affect the original
259+ .{ "newHeaders.set('X-Custom', 'test-value')" , "undefined" },
260+ .{ "newHeaders.get('X-Custom')" , "test-value" },
261+ .{ "originalHeaders.get('X-Custom')" , "null" },
262+ .{ "originalHeaders.has('X-Custom')" , "false" },
263+ }, .{});
262264}
0 commit comments