Skip to content

Commit fffc495

Browse files
marco-ippolitoUlisesGascon
authored andcommitted
module: add application/json in accept header when fetching json module
PR-URL: #50119 Refs: #50116 Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Jacob Smith <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]>
1 parent 5e6057c commit fffc495

File tree

2 files changed

+32
-6
lines changed

2 files changed

+32
-6
lines changed

lib/internal/modules/esm/fetch_module.js

+20-6
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,32 @@ function isRedirect(statusCode) {
134134
}
135135
}
136136

137+
/**
138+
* @typedef AcceptMimes possible values of Accept header when fetching a module
139+
* @property {Promise<string> | string} default default Accept header value.
140+
* @property {Record<string, string>} json Accept header value when fetching module with importAttributes json.
141+
* @type {AcceptMimes}
142+
*/
143+
const acceptMimes = {
144+
__proto_: null,
145+
default: '*/*',
146+
json: 'application/json,*/*;charset=utf-8;q=0.5',
147+
};
148+
137149
/**
138150
* @param {URL} parsed
139151
* @returns {Promise<CacheEntry> | CacheEntry}
140152
*/
141-
function fetchWithRedirects(parsed) {
153+
function fetchWithRedirects(parsed, context) {
142154
const existing = cacheForGET.get(parsed.href);
143155
if (existing) {
144156
return existing;
145157
}
146158
const handler = parsed.protocol === 'http:' ? HTTPGet : HTTPSGet;
147159
const result = (async () => {
160+
const accept = acceptMimes[context.importAttributes?.type] ?? acceptMimes.default;
148161
const req = handler(parsed, {
149-
headers: { Accept: '*/*' },
162+
headers: { Accept: accept },
150163
});
151164
// Note that `once` is used here to handle `error` and that it hits the
152165
// `finally` on network error/timeout.
@@ -162,7 +175,7 @@ function fetchWithRedirects(parsed) {
162175
'cannot redirect to non-network location',
163176
);
164177
}
165-
const entry = await fetchWithRedirects(location);
178+
const entry = await fetchWithRedirects(location, context);
166179
cacheForGET.set(parsed.href, entry);
167180
return entry;
168181
}
@@ -262,7 +275,8 @@ async function isLocalAddress(hostname) {
262275
* @param {ESModuleContext} context
263276
* @returns {ReturnType<typeof fetchWithRedirects>}
264277
*/
265-
function fetchModule(parsed, { parentURL }) {
278+
function fetchModule(parsed, context) {
279+
const { parentURL } = context;
266280
const { href } = parsed;
267281
const existing = cacheForGET.get(href);
268282
if (existing) {
@@ -277,10 +291,10 @@ function fetchModule(parsed, { parentURL }) {
277291
'http can only be used to load local resources (use https instead).',
278292
);
279293
}
280-
return fetchWithRedirects(parsed);
294+
return fetchWithRedirects(parsed, context);
281295
});
282296
}
283-
return fetchWithRedirects(parsed);
297+
return fetchWithRedirects(parsed, context);
284298
}
285299

286300
module.exports = {

test/es-module/test-http-imports.mjs

+12
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ for (const { protocol, createServer } of [
6868
const server = createServer(function(_req, res) {
6969
const url = new URL(_req.url, host);
7070
const redirect = url.searchParams.get('redirect');
71+
72+
if (url.pathname === 'json') {
73+
common.mustCall(() => assert.strictEqual(_req.header.content, 'application/json,*/*;charset=utf-8;q=0.5'));
74+
}
75+
7176
if (url.pathname === '/not-found') {
7277
res.writeHead(404);
7378
res.end();
@@ -204,6 +209,13 @@ for (const { protocol, createServer } of [
204209
{ code: 'ERR_MODULE_NOT_FOUND' },
205210
);
206211

212+
const jsonUrl = new URL(url.href + 'json');
213+
jsonUrl.searchParams.set('mime', 'application/json');
214+
jsonUrl.searchParams.set('body', '{"x": 1}');
215+
const json = await import(jsonUrl.href, { with: { type: 'json' } });
216+
assert.deepStrictEqual(Object.keys(json), ['default']);
217+
assert.strictEqual(json.default.x, 1);
218+
207219
server.close();
208220
}
209221
}

0 commit comments

Comments
 (0)