fix cors function for alpine linux (#4091)

I provide docker images with alpine linux and tested the new cors
approach.

It didn't work because after calling

```js
  const dispatcher = new Agent({ connect: { lookup: (_h, _o, cb) => cb(null, address, family) } });
```

the dispatcher variable was undefined.

This PR solves this and I tested this under debian too.

The mix of internal fetch and newer undici did not work and alpine needs
additionally the `process.nextTick`.

---------

Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
This commit is contained in:
Karsten Hassel
2026-04-05 21:42:32 +02:00
committed by GitHub
parent 0da343b961
commit 9b97add1ae
2 changed files with 13 additions and 5 deletions
+10 -3
View File
@@ -2,7 +2,7 @@ const dns = require("node:dns");
const fs = require("node:fs");
const path = require("node:path");
const ipaddr = require("ipaddr.js");
const { Agent } = require("undici");
const undici = require("undici");
const Log = require("logger");
const startUp = new Date();
@@ -98,9 +98,16 @@ async function cors (req, res) {
}
// Pin the validated IP — fetch() reuses it instead of doing its own DNS lookup
const dispatcher = new Agent({ connect: { lookup: (_h, _o, cb) => cb(null, address, family) } });
const dispatcher = new undici.Agent({
connect: {
lookup: (_h, _o, cb) => {
const addresses = [{ address: address, family: family }];
process.nextTick(() => cb(null, addresses));
}
}
});
const response = await fetch(url, { dispatcher, headers: headersToSend });
const response = await undici.fetch(url, { dispatcher, headers: headersToSend });
if (response.ok) {
for (const header of expectedReceivedHeaders) {
const headerValue = response.headers.get(header);
@@ -1,9 +1,10 @@
// Tests use vi.spyOn on shared module objects (dns, global.fetch).
// Tests use vi.spyOn on shared module objects (dns, undici).
// vi.spyOn modifies the object property directly on the cached module instance, so it
// is intercepted by server_functions.js regardless of the Module.prototype.require override
// in vitest-setup.js. restoreAllMocks:true auto-restores spies, but may reuse the same
// spy instance — mockClear() is called explicitly in beforeEach to reset call history.
const dns = require("node:dns");
const undici = require("undici");
const { cors, getUserAgent, replaceSecretPlaceholder } = require("#server_functions");
describe("server_functions tests", () => {
@@ -41,7 +42,7 @@ describe("server_functions tests", () => {
// vi.spyOn may return the same spy instance across tests when restoreAllMocks
// restores-but-reuses; mockClear() explicitly resets call history each time.
fetchSpy = vi.spyOn(global, "fetch");
fetchSpy = vi.spyOn(undici, "fetch");
fetchSpy.mockClear();
fetchSpy.mockImplementation(() => Promise.resolve({
headers: { get: fetchResponseHeadersGet },