pinokiod 8.2.31 → 8.2.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -74,8 +74,6 @@ class Forwarders {
|
|
|
74
74
|
const label = String(dnsName).split('.')[0]
|
|
75
75
|
const target = `${this.scheme}://${dnsName}:${port}`
|
|
76
76
|
const proxy = httpProxy.createProxyServer({ target, agent: this.agent(), changeOrigin: true, secure: true, ws: true })
|
|
77
|
-
proxy.on('proxyReq', (proxyReq) => { proxyReq.setHeader(FORWARDED_HEADER, '1') })
|
|
78
|
-
proxy.on('proxyReqWs', (proxyReq) => { proxyReq.setHeader(FORWARDED_HEADER, '1') })
|
|
79
77
|
proxy.on('error', (error, req, res) => {
|
|
80
78
|
const message = `Could not reach ${dnsName}: ${error && error.message ? error.message : error}`
|
|
81
79
|
if (res && typeof res.writeHead === 'function' && !res.headersSent) {
|
|
@@ -85,7 +83,13 @@ class Forwarders {
|
|
|
85
83
|
res.destroy()
|
|
86
84
|
}
|
|
87
85
|
})
|
|
88
|
-
|
|
86
|
+
// The headers go out as the incoming request's headers. Setting them in http-proxy's proxyReq
|
|
87
|
+
// hook instead would throw: with the proxy agent the hook fires once the CONNECT completes, and
|
|
88
|
+
// by then the outgoing headers are already written.
|
|
89
|
+
const mark = (req) => {
|
|
90
|
+
for (const name of STRIPPED_HEADERS) delete req.headers[name]
|
|
91
|
+
req.headers[FORWARDED_HEADER] = '1'
|
|
92
|
+
}
|
|
89
93
|
const server = http.createServer((req, res) => {
|
|
90
94
|
const url = new URL(req.url, 'http://127.0.0.1')
|
|
91
95
|
if (url.pathname === OPEN_PATH) {
|
|
@@ -100,11 +104,11 @@ class Forwarders {
|
|
|
100
104
|
res.end()
|
|
101
105
|
return
|
|
102
106
|
}
|
|
103
|
-
|
|
107
|
+
mark(req)
|
|
104
108
|
proxy.web(req, res)
|
|
105
109
|
})
|
|
106
110
|
server.on('upgrade', (req, socket, head) => {
|
|
107
|
-
|
|
111
|
+
mark(req)
|
|
108
112
|
proxy.ws(req, socket, head)
|
|
109
113
|
})
|
|
110
114
|
// every connection on both sides, upgraded ones included, so stopAll can end a stream a
|
package/package.json
CHANGED
|
@@ -55,6 +55,39 @@ test('a forwarder relays requests with the forwarded header, the peer as Host, a
|
|
|
55
55
|
assert.equal(target.seen[0].headers['x-pinokio-source-host'], undefined)
|
|
56
56
|
})
|
|
57
57
|
|
|
58
|
+
// A forward proxy for plain http targets: the real ProxyAgent sends it absolute URLs, and
|
|
59
|
+
// connects asynchronously, which is what broke the proxyReq-hook version in production.
|
|
60
|
+
async function forwardProxy(t) {
|
|
61
|
+
const server = http.createServer((req, res) => {
|
|
62
|
+
const target = new URL(req.url)
|
|
63
|
+
const upstream = http.request({ host: target.hostname, port: target.port, path: target.pathname + target.search, method: req.method, headers: req.headers }, (answer) => {
|
|
64
|
+
res.writeHead(answer.statusCode, answer.headers)
|
|
65
|
+
answer.pipe(res)
|
|
66
|
+
})
|
|
67
|
+
upstream.on('error', (error) => { res.writeHead(502); res.end(error.message) })
|
|
68
|
+
req.pipe(upstream)
|
|
69
|
+
})
|
|
70
|
+
server.listen(0, '127.0.0.1')
|
|
71
|
+
await once(server, 'listening')
|
|
72
|
+
t.after(() => { server.closeAllConnections(); server.close() })
|
|
73
|
+
return `http://127.0.0.1:${server.address().port}`
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
test('through the real proxy agent, whose connection completes later, the forwarded header still goes out and nothing throws', async (t) => {
|
|
77
|
+
const target = await peer(t)
|
|
78
|
+
const proxyUrl = await forwardProxy(t)
|
|
79
|
+
const forwarders = new Forwarders({ proxyUrl: () => proxyUrl, serverPort: () => 42000, scheme: 'http' })
|
|
80
|
+
t.after(() => forwarders.stopAll())
|
|
81
|
+
const local = await forwarders.open('127.0.0.1', target.port)
|
|
82
|
+
const answer = await get(local, '/ui/?a=1', { 'X-Pinokio-Peer': '1' })
|
|
83
|
+
assert.equal(answer.status, 200)
|
|
84
|
+
const body = JSON.parse(answer.body)
|
|
85
|
+
assert.equal(body.forwarded, '1')
|
|
86
|
+
assert.equal(body.peer, null)
|
|
87
|
+
assert.equal(body.host, `127.0.0.1:${target.port}`)
|
|
88
|
+
assert.equal(target.seen.length, 1)
|
|
89
|
+
})
|
|
90
|
+
|
|
58
91
|
test('two opens of the same peer and port at once share one forwarder', async (t) => {
|
|
59
92
|
const target = await peer(t)
|
|
60
93
|
const forwarders = new Forwarders({ proxyUrl: () => null, serverPort: () => 42000, scheme: 'http' })
|