Open Bug 1697114 Opened 4 years ago Updated 2 years ago

Headers API iterator does not copy the list

Categories

(Core :: DOM: Networking, defect, P3)

Firefox 88
defect

Tracking

()

UNCONFIRMED

People

(Reporter: ricea, Unassigned)

References

(Blocks 1 open bug)

Details

(Whiteboard: [necko-triaged])

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36

Steps to reproduce:

let headers = new Headers([["a", "1"], ["b", "2"], ["c", "3"], ["d", "4"], ["e", "5"]]);
headers.forEach(function (v, k) {
if (Number(v) < 10) headers.set("A" + v, "extra");
console.log(k, v); // a 1; b 2; c 3; d 4; e 5
});

Actual results:

a 1
a1 extra
b 2
b 2
c 3
c 3
d 4
d 4
e 5
e 5

Expected results:

a 1
b 2
c 3
d 4
e 5

See https://fetch.spec.whatwg.org/#ref-for-concept-header-list-sort-and-combine "The value pairs to iterate over are the return value of running sort and combine with this’s header list.", implying that it's actually a copy of the headers that are iterated over.

CC:d annevk for confirmation that my interpretation of the standard is correct.

It seems somewhat unfortunate that this would make it different from FormData and URLSearchParams. We did this to allow implementations to implement Headers in various ways, but I'm not sure we considered this consequence. Youenn, Domenic, thoughts?

(If you all think this is acceptable, we'll fix this in due course.)

Component: Untriaged → DOM: Networking
Flags: needinfo?(youennf)
Flags: needinfo?(d)
Product: Firefox → Core

It does seem unfortunate, but I can't tell how you would specify the alternative. If you want them sorted and combined... I guess you would need to update set() and append() to no longer do an append, but instead an insert into the appropriate location? There's a definite conflict here between FormData and URLSearchParams, which use insertion order, and Headers, which has a definite order.

Also I don't understand why Firefox would output b, c, d, and e twice each; that seems undesirable in any case.

Flags: needinfo?(d)

That's because the code keeps inserting aX headers before the current point of iteration I think.

And yeah, there's definitely differences. Headers used to be a multimap as well until we realized that would not be needed. And the sorting was added to prevent code from relying on server order of headers and such.

Blocks: fetch
Severity: -- → S3
Priority: -- → P3
Whiteboard: [necko-triaged]

Clear a needinfo that is pending on an inactive user.

Inactive users most likely will not respond; if the missing information is essential and cannot be collected another way, the bug maybe should be closed as INCOMPLETE.

For more information, please visit BugBot documentation.

Flags: needinfo?(youennf)

Same behaviour in Chrome. Haven't checked safari yet.

FWIW, Chrome, Safari and Firefox all output the same thing for me:

a 1
a1 extra
b 2
b 2
c 3
c 3
d 4
d 4
e 5
e 5

So at least there doesn't seem to be an interop issue here at the moment.

You need to log in before you can comment on or make changes to this bug.