Skip to content

Commit a217002

Browse files
authored
fix: fix EnvHttpProxyAgent for the Node.js bundle (nodejs#4064)
* fix: fix EnvHttpProxyAgent for the Node.js bundle The Dispatcher needs some methods from lib/api for EnvHttpProxyAgent, otherwise it's incomplete. * fixup! fix: fix EnvHttpProxyAgent for the Node.js bundle
1 parent 782f06b commit a217002

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

index-fetch.js

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ module.exports.createFastMessageEvent = createFastMessageEvent
2626

2727
module.exports.EventSource = require('./lib/web/eventsource/eventsource').EventSource
2828

29+
const api = require('./lib/api')
30+
const Dispatcher = require('./lib/dispatcher/dispatcher')
31+
Object.assign(Dispatcher.prototype, api)
2932
// Expose the fetch implementation to be enabled in Node.js core via a flag
3033
module.exports.EnvHttpProxyAgent = EnvHttpProxyAgent
3134
module.exports.getGlobalDispatcher = getGlobalDispatcher
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
'use strict'
2+
3+
const { tspl } = require('@matteo.collina/tspl')
4+
const { describe, test, after, before } = require('node:test')
5+
const { EnvHttpProxyAgent, setGlobalDispatcher } = require('../index-fetch')
6+
const http = require('node:http')
7+
const net = require('node:net')
8+
const { once } = require('node:events')
9+
10+
const env = { ...process.env }
11+
12+
describe('EnvHttpProxyAgent and setGlobalDispatcher', () => {
13+
before(() => {
14+
['HTTP_PROXY', 'http_proxy', 'HTTPS_PROXY', 'https_proxy', 'NO_PROXY', 'no_proxy'].forEach((varname) => {
15+
delete process.env[varname]
16+
})
17+
})
18+
19+
after(() => {
20+
process.env = { ...env }
21+
})
22+
23+
test('should work together from the Node.js bundle', async (t) => {
24+
const { strictEqual } = tspl(t, { plan: 3 })
25+
26+
// Instead of using mocks, start a real server and a minimal proxy server
27+
// in order to exercise the actual paths in EnvHttpProxyAgent from the
28+
// Node.js bundle.
29+
const server = http.createServer((req, res) => { res.end('Hello world') })
30+
server.on('error', err => { console.log('Server error', err) })
31+
server.listen(0)
32+
await once(server, 'listening')
33+
t.after(() => { server.close() })
34+
35+
const proxy = http.createServer()
36+
proxy.on('connect', (req, clientSocket, head) => {
37+
// Check that the proxy is actually used to tunnel the request sent below.
38+
const [hostname, port] = req.url.split(':')
39+
strictEqual(hostname, 'localhost')
40+
strictEqual(port, server.address().port.toString())
41+
42+
const serverSocket = net.connect(port, hostname, () => {
43+
clientSocket.write(
44+
'HTTP/1.1 200 Connection Established\r\n' +
45+
'Proxy-agent: Node.js-Proxy\r\n' +
46+
'\r\n'
47+
)
48+
serverSocket.write(head)
49+
clientSocket.pipe(serverSocket)
50+
serverSocket.pipe(clientSocket)
51+
})
52+
53+
serverSocket.on('error', () => {
54+
clientSocket.write('HTTP/1.1 500 Connection Error\r\n\r\n')
55+
clientSocket.end()
56+
})
57+
})
58+
59+
proxy.on('error', (err) => { console.log('Proxy error', err) })
60+
61+
proxy.listen(0)
62+
await once(proxy, 'listening')
63+
t.after(() => { proxy.close() })
64+
65+
// Use setGlobalDispatcher and EnvHttpProxyAgent from Node.js
66+
// and make sure that they work together.
67+
const proxyAddress = `http://localhost:${proxy.address().port}`
68+
const serverAddress = `http://localhost:${server.address().port}`
69+
process.env.http_proxy = proxyAddress
70+
setGlobalDispatcher(new EnvHttpProxyAgent())
71+
72+
const res = await fetch(serverAddress)
73+
strictEqual(await res.text(), 'Hello world')
74+
})
75+
})

0 commit comments

Comments
 (0)