Skip to content

Commit ead0846

Browse files
committed
Support Node.js http.ClientRequestArgs["headers"] array
Signed-off-by: Timo Stamm <[email protected]>
1 parent 2b43a76 commit ead0846

File tree

2 files changed

+48
-9
lines changed

2 files changed

+48
-9
lines changed

packages/connect-node/src/node-universal-header.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,25 @@ describe("webHeaderToNodeHeaders()", () => {
144144
d: ["d1", "d2"],
145145
});
146146
});
147+
it("should accept default node headers array", () => {
148+
const nodeDefaults: string[] = [
149+
"a", "a",
150+
"b", "b1",
151+
"b", "b2",
152+
"c", "123",
153+
];
154+
const webHeaders: HeadersInit = [
155+
["b", "web"],
156+
["c", "456"],
157+
["d", "d1"],
158+
["d", "d2"],
159+
];
160+
const h = webHeaderToNodeHeaders(webHeaders, nodeDefaults);
161+
expect(h).toEqual({
162+
a: "a",
163+
b: ["b1", "b2", "web"],
164+
c: ["123", "456"],
165+
d: ["d1", "d2"],
166+
});
167+
});
147168
});

packages/connect-node/src/node-universal-header.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,30 +54,48 @@ export function nodeHeaderToWebHeader(
5454
/**
5555
* Convert a fetch API Headers object to a Node.js headers object.
5656
*
57-
* Optionally accepts default Node.js headers. If provided, fetch API headers
58-
* are appended to the defaults. The original defaults headers are not modified.
57+
* Optionally accepts default Node.js headers as a dict or an array.
58+
* If provided, fetch API headers are appended to the defaults.
59+
* The original defaults headers are not modified.
5960
*/
6061
export function webHeaderToNodeHeaders(
6162
headersInit: HeadersInit,
62-
defaultNodeHeaders?: http.OutgoingHttpHeaders,
63+
defaultNodeHeaders?: http.OutgoingHttpHeaders | readonly string[],
6364
): http.OutgoingHttpHeaders;
6465
export function webHeaderToNodeHeaders(
6566
headersInit: HeadersInit | undefined,
6667
): http.OutgoingHttpHeaders | undefined;
6768
export function webHeaderToNodeHeaders(
6869
headersInit: HeadersInit | undefined,
69-
defaultNodeHeaders?: http.OutgoingHttpHeaders,
70+
defaultNodeHeaders?: http.OutgoingHttpHeaders | readonly string[],
7071
): http.OutgoingHttpHeaders | undefined {
7172
if (headersInit === undefined && defaultNodeHeaders === undefined) {
7273
return undefined;
7374
}
7475
const o = Object.create(null) as http.OutgoingHttpHeaders;
7576
if (defaultNodeHeaders !== undefined) {
76-
for (const [key, value] of Object.entries(defaultNodeHeaders)) {
77-
if (Array.isArray(value)) {
78-
o[key] = value.concat();
79-
} else if (value !== undefined) {
80-
o[key] = value;
77+
if (Array.isArray(defaultNodeHeaders)) {
78+
// headers may be an Array where the keys and values are in the same list.
79+
// It is _not_ a list of tuples. So, the even-numbered offsets are key values,
80+
// and the odd-numbered offsets are the associated values.
81+
for (let i = 0; i + 1 < defaultNodeHeaders.length; i += 2) {
82+
const key = defaultNodeHeaders[i];
83+
const value = defaultNodeHeaders[i + 1];
84+
if (Array.isArray(o[key])) {
85+
o[key].push(value);
86+
} else if (typeof o[key] == "string") {
87+
o[key] = [o[key], value];
88+
} else {
89+
o[key] = value;
90+
}
91+
}
92+
} else {
93+
for (const [key, value] of Object.entries(defaultNodeHeaders)) {
94+
if (Array.isArray(value)) {
95+
o[key] = value.concat();
96+
} else if (value !== undefined) {
97+
o[key] = value;
98+
}
8199
}
82100
}
83101
}

0 commit comments

Comments
 (0)