mirror of https://github.com/nodejs/corepack.git
fix: correctly set `Dispatcher` prototype for `ProxyAgent` (#451)
In an attempt to bundle only a subset of Undici code, we forgot to take some side-effect into account.
This commit is contained in:
parent
07b58cc65a
commit
73d9a1e2d2
|
|
@ -52,6 +52,9 @@
|
|||
"v8-compile-cache": "^2.3.0",
|
||||
"which": "^4.0.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"undici-types": "6.x"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "rm -rf dist shims && run build:bundle && ts-node ./mkshims.ts",
|
||||
"build:bundle": "esbuild ./sources/_lib.ts --bundle --platform=node --target=node18.17.0 --external:corepack --outfile='./dist/lib/corepack.cjs' --resolve-extensions='.ts,.mjs,.js'",
|
||||
|
|
|
|||
|
|
@ -92,6 +92,8 @@ export async function fetchUrlStream(input: string | URL, init?: RequestInit) {
|
|||
return stream;
|
||||
}
|
||||
|
||||
let ProxyAgent: typeof import('undici').ProxyAgent;
|
||||
|
||||
async function getProxyAgent(input: string | URL) {
|
||||
const {getProxyForUrl} = await import(`proxy-from-env`);
|
||||
|
||||
|
|
@ -100,11 +102,20 @@ async function getProxyAgent(input: string | URL) {
|
|||
|
||||
if (!proxy) return undefined;
|
||||
|
||||
// Doing a deep import here since undici isn't tree-shakeable
|
||||
const {default: ProxyAgent} = (await import(
|
||||
// @ts-expect-error No types for this specific file
|
||||
`undici/lib/proxy-agent.js`
|
||||
)) as { default: typeof import('undici').ProxyAgent };
|
||||
if (ProxyAgent == null) {
|
||||
// Doing a deep import here since undici isn't tree-shakeable
|
||||
const [api, Dispatcher, _ProxyAgent] = await Promise.all([
|
||||
// @ts-expect-error internal module is untyped
|
||||
import(`undici/lib/api/index.js`),
|
||||
// @ts-expect-error internal module is untyped
|
||||
import(`undici/lib/dispatcher/dispatcher.js`),
|
||||
// @ts-expect-error internal module is untyped
|
||||
import(`undici/lib/dispatcher/proxy-agent.js`),
|
||||
]);
|
||||
|
||||
Object.assign(Dispatcher.default.prototype, api.default);
|
||||
ProxyAgent = _ProxyAgent.default;
|
||||
}
|
||||
|
||||
return new ProxyAgent(proxy);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import {createHash} from 'node:crypto';
|
||||
import {once} from 'node:events';
|
||||
import {createServer} from 'node:http';
|
||||
import {connect} from 'node:net';
|
||||
import {gzipSync} from 'node:zlib';
|
||||
|
||||
function createSimpleTarArchive(fileName, fileContent, mode = 0o644) {
|
||||
|
|
@ -110,12 +111,47 @@ const server = createServer((req, res) => {
|
|||
res.writeHead(500).end(`Internal Error`);
|
||||
throw new Error(`unsupported request`, {cause: {url: req.url, packageName}});
|
||||
}
|
||||
}).listen(0, `localhost`);
|
||||
});
|
||||
|
||||
if (process.env.AUTH_TYPE === `PROXY`) {
|
||||
const proxy = createServer((req, res) => {
|
||||
res.writeHead(200, {[`Content-Type`]: `text/plain`});
|
||||
res.end(`okay`);
|
||||
});
|
||||
proxy.on(`connect`, (req, clientSocket, head) => {
|
||||
if (req.url !== `example.com:80`) {
|
||||
// Reject all requests except those to `example.com`
|
||||
clientSocket.end(`HTTP/1.1 404 Not Found\r\n\r\n`);
|
||||
return;
|
||||
}
|
||||
const {address, port} = server.address();
|
||||
const serverSocket = connect(port, address, () => {
|
||||
clientSocket.write(`HTTP/1.1 200 Connection Established\r\n` +
|
||||
`Proxy-agent: Node.js-Proxy\r\n` +
|
||||
`\r\n`);
|
||||
serverSocket.write(head);
|
||||
serverSocket.pipe(clientSocket);
|
||||
clientSocket.pipe(serverSocket);
|
||||
});
|
||||
});
|
||||
proxy.listen(0, `localhost`);
|
||||
await once(proxy, `listening`);
|
||||
const {address, port} = proxy.address();
|
||||
process.env.ALL_PROXY = `http://${address.includes(`:`) ? `[${address}]` : address}:${port}`;
|
||||
|
||||
proxy.unref();
|
||||
}
|
||||
|
||||
server.listen(0, `localhost`);
|
||||
await once(server, `listening`);
|
||||
|
||||
const {address, port} = server.address();
|
||||
switch (process.env.AUTH_TYPE) {
|
||||
case `PROXY`:
|
||||
// The proxy set up above will redirect all requests to our custom registry,
|
||||
process.env.COREPACK_NPM_REGISTRY = `http://user:pass@example.com`;
|
||||
break;
|
||||
|
||||
case `COREPACK_NPM_REGISTRY`:
|
||||
process.env.COREPACK_NPM_REGISTRY = `http://user:pass@${address.includes(`:`) ? `[${address}]` : address}:${port}`;
|
||||
break;
|
||||
|
|
@ -137,8 +173,11 @@ switch (process.env.AUTH_TYPE) {
|
|||
if (process.env.NOCK_ENV === `replay`) {
|
||||
const originalFetch = globalThis.fetch;
|
||||
globalThis.fetch = function fetch(i) {
|
||||
if (!`${i}`.startsWith(`http://${address.includes(`:`) ? `[${address}]` : address}:${port}`))
|
||||
throw new Error;
|
||||
if (!`${i}`.startsWith(
|
||||
process.env.AUTH_TYPE === `PROXY` ?
|
||||
`http://example.com` :
|
||||
`http://${address.includes(`:`) ? `[${address}]` : address}:${port}`))
|
||||
throw new Error(`Unexpected request to ${i}`);
|
||||
|
||||
return Reflect.apply(originalFetch, this, arguments);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -805,7 +805,7 @@ it(`should download yarn berry from custom registry`, async () => {
|
|||
});
|
||||
});
|
||||
|
||||
for (const authType of [`COREPACK_NPM_REGISTRY`, `COREPACK_NPM_TOKEN`, `COREPACK_NPM_PASSWORD`]) {
|
||||
for (const authType of [`COREPACK_NPM_REGISTRY`, `COREPACK_NPM_TOKEN`, `COREPACK_NPM_PASSWORD`, `PROXY`]) {
|
||||
describe(`custom registry with auth ${authType}`, () => {
|
||||
beforeEach(() => {
|
||||
process.env.AUTH_TYPE = authType; // See `_registryServer.mjs`
|
||||
|
|
|
|||
29
yarn.lock
29
yarn.lock
|
|
@ -730,13 +730,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@fastify/busboy@npm:^2.0.0":
|
||||
version: 2.1.0
|
||||
resolution: "@fastify/busboy@npm:2.1.0"
|
||||
checksum: 10c0/7bb641080aac7cf01d88749ad331af10ba9ec3713ec07cabbe833908c75df21bd56249bb6173bdec07f5a41896b21e3689316f86684c06635da45f91ff4565a2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@humanwhocodes/config-array@npm:^0.11.13":
|
||||
version: 0.11.13
|
||||
resolution: "@humanwhocodes/config-array@npm:0.11.13"
|
||||
|
|
@ -1303,11 +1296,11 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"@types/node@npm:*, @types/node@npm:^20.4.6":
|
||||
version: 20.10.5
|
||||
resolution: "@types/node@npm:20.10.5"
|
||||
version: 20.12.6
|
||||
resolution: "@types/node@npm:20.12.6"
|
||||
dependencies:
|
||||
undici-types: "npm:~5.26.4"
|
||||
checksum: 10c0/be30609aae0bfe492097815f166ccc07f465220cb604647fa4e5ec05a1d16c012a41b82b5f11ecfe2485cbb479d4d20384b95b809ca0bcff6d94d5bbafa645bb
|
||||
checksum: 10c0/48ce732162cd6c02656aa5f996f0e695b57fdeb1ae762fbaa966afac2dcdcf52cb56be5ce1efb4babf8f97c2de545889aebc7f43c2e86f033487245c41fa1e6b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -5991,19 +5984,17 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"undici-types@npm:~5.26.4":
|
||||
version: 5.26.5
|
||||
resolution: "undici-types@npm:5.26.5"
|
||||
checksum: 10c0/bb673d7876c2d411b6eb6c560e0c571eef4a01c1c19925175d16e3a30c4c428181fb8d7ae802a261f283e4166a0ac435e2f505743aa9e45d893f9a3df017b501
|
||||
"undici-types@npm:6.x":
|
||||
version: 6.12.0
|
||||
resolution: "undici-types@npm:6.12.0"
|
||||
checksum: 10c0/439ad3a384b4b392ff7fbd98b50a29ea4ca0ca1899f29a967a043abb45f0e67a786b058f59a327b3007079cff35ed5337d20603f06b6bb6a5b27539ebecd9792
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"undici@npm:^6.6.1":
|
||||
version: 6.6.2
|
||||
resolution: "undici@npm:6.6.2"
|
||||
dependencies:
|
||||
"@fastify/busboy": "npm:^2.0.0"
|
||||
checksum: 10c0/c8c8a436059b13603f67ed4d917b4ba6d9ef282ac55c932c4790ee1a1c8cad1369da3c11b6e0b9df5a95ed1849cb98fa2f2310f6d0f9331dd359286c912497d2
|
||||
version: 6.12.0
|
||||
resolution: "undici@npm:6.12.0"
|
||||
checksum: 10c0/5bbfd261ea20c8ed6bb3a22703acdae80cb40b1de0595a1c4df46f6602db78d7a387174c292c5640e339422acb1bfd1d2e0987ec086c057ccc24806edfd4688b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue