56 lines
2.2 KiB
JavaScript
56 lines
2.2 KiB
JavaScript
import { readFileSync } from 'node:fs'
|
|
import { Agent, fetch as undiciFetch, ProxyAgent } from 'undici'
|
|
import { OUTBOUND_PROXY_PORTS, outboundProxyScopeEnabled } from '../../../platform/lib/outbound-proxy.mjs'
|
|
|
|
const LOOPBACK = '127.0.0.1'
|
|
const DEFAULT_ROUTING_STATE = '/run/dsh-platform/outbound-proxy-routing.json'
|
|
|
|
export const PROXY_SCOPE_PORTS = Object.freeze({
|
|
updates: OUTBOUND_PROXY_PORTS.updates,
|
|
platform: OUTBOUND_PROXY_PORTS.platform,
|
|
dshCore: OUTBOUND_PROXY_PORTS.dshCore,
|
|
dshPlugins: OUTBOUND_PROXY_PORTS.dshPlugins,
|
|
agent: OUTBOUND_PROXY_PORTS.agentNetwork,
|
|
terminal: OUTBOUND_PROXY_PORTS.managementTerminal,
|
|
provider: OUTBOUND_PROXY_PORTS.modelApi,
|
|
sharedDsh: OUTBOUND_PROXY_PORTS.sharedDsh,
|
|
})
|
|
|
|
const CONFIGURATION_SCOPE = Object.freeze({
|
|
updates: 'updates', platform: 'platform', dshCore: 'dshCore', dshPlugins: 'dshPlugins',
|
|
agent: 'agentNetwork', terminal: 'managementTerminal',
|
|
})
|
|
|
|
function proxyEnabled(path, scope) {
|
|
try {
|
|
const state = JSON.parse(readFileSync(path, 'utf8'))
|
|
if (state?.schema !== 1 || typeof state.enabled !== 'boolean') return true
|
|
const configurationScope = CONFIGURATION_SCOPE[scope]
|
|
return configurationScope === undefined ? true : outboundProxyScopeEnabled(state, configurationScope)
|
|
} catch {
|
|
return true
|
|
}
|
|
}
|
|
|
|
export function createScopedFetch(scope, {
|
|
fetchImpl = undiciFetch,
|
|
routingStatePath = DEFAULT_ROUTING_STATE,
|
|
createDirectDispatcher = () => new Agent(),
|
|
createProxyDispatcher = options => new ProxyAgent(options),
|
|
} = {}) {
|
|
const port = PROXY_SCOPE_PORTS[scope]
|
|
if (port === undefined) throw new TypeError(`unknown outbound proxy scope ${JSON.stringify(scope)}`)
|
|
const directDispatcher = createDirectDispatcher()
|
|
const proxyDispatcher = createProxyDispatcher({ uri: `http://${LOOPBACK}:${String(port)}` })
|
|
const scopedFetch = (input, init = {}) => fetchImpl(input, {
|
|
...init,
|
|
dispatcher: proxyEnabled(routingStatePath, scope) ? proxyDispatcher : directDispatcher,
|
|
})
|
|
scopedFetch.close = async () => {
|
|
await Promise.all([directDispatcher.close(), proxyDispatcher.close()])
|
|
}
|
|
return scopedFetch
|
|
}
|
|
|
|
export const scopedFetchInternals = Object.freeze({ proxyEnabled })
|