Skip to main content

Overview

EPR LAPS Backend supports forward proxy configuration for outbound HTTP/HTTPS requests. This is essential in CDP environments where external API calls must route through a proxy.
The proxy is configured via the HTTP_PROXY environment variable and is automatically applied to multiple HTTP clients.

Configuration

Environment Variable

Set the HTTP_PROXY environment variable to enable proxy support:
export HTTP_PROXY=http://proxy.example.com:8080
npm start
Configuration in src/config.js:
httpProxy: {
  doc: 'HTTP Proxy URL',
  format: String,
  nullable: true,
  default: null,
  env: 'HTTP_PROXY'
}

Proxy Setup Implementation

The proxy is configured in src/common/helpers/proxy/setup-proxy.js:
import { ProxyAgent, setGlobalDispatcher } from 'undici'
import { bootstrap } from 'global-agent'
import { createLogger } from '../logging/logger.js'
import { config } from '../../../config.js'

const logger = createLogger()

/**
 * If HTTP_PROXY is set setupProxy() will enable it globally
 * for a number of http clients.
 * Node Fetch will still need to pass a ProxyAgent in on each call.
 */
export function setupProxy() {
  const proxyUrl = config.get('httpProxy')

  if (proxyUrl) {
    logger.info('setting up global proxies')

    // Undici proxy
    setGlobalDispatcher(new ProxyAgent(proxyUrl))

    // global-agent (axios/request/and others)
    bootstrap()
    globalThis.GLOBAL_AGENT.HTTP_PROXY = proxyUrl
  }
}

Supported HTTP Clients

The proxy setup supports multiple HTTP clients:
Undici is the recommended HTTP client and has global proxy support via setGlobalDispatcher.
Using undici with global proxy:
import { fetch } from 'undici'

// Proxy is automatically applied via setGlobalDispatcher
const response = await fetch('http://localhost:3001/data')
const data = await response.json()
The global dispatcher is set in setupProxy(), so all undici fetch calls automatically use the proxy.

2. Hapi Wreck

Wreck (used by Hapi) automatically respects the global proxy:
import Wreck from '@hapi/wreck'

const { payload } = await Wreck.get('http://localhost:3001/data')

3. Axios and Other Clients

Via global-agent:
import axios from 'axios'

// Proxy is automatically applied via global-agent
const response = await axios.get('http://localhost:3001/data')
The global-agent library intercepts HTTP/HTTPS requests from most Node.js HTTP clients.

4. Node Fetch (Manual Configuration)

Node Fetch requires manual proxy configuration on each request. The global dispatcher does not apply.
Manual proxy agent for node-fetch:
import fetch from 'node-fetch'
import { ProxyAgent } from 'undici'
import { config } from './config.js'

const proxyUrl = config.get('httpProxy')

const response = await fetch('http://localhost:3001/data', {
  dispatcher: new ProxyAgent({
    uri: proxyUrl,
    keepAliveTimeout: 10,
    keepAliveMaxTimeout: 10
  })
})

Custom HTTP Clients

For HTTP clients that don’t automatically use the global proxy, manually configure a ProxyAgent:
import { ProxyAgent } from 'undici'
import { config } from './config.js'

const proxyUrl = config.get('httpProxy')

const response = await fetch(url, {
  dispatcher: new ProxyAgent({
    uri: proxyUrl,
    keepAliveTimeout: 10,
    keepAliveMaxTimeout: 10
  })
})

Initialization

The proxy setup is called during application initialization:
import { setupProxy } from './common/helpers/proxy/setup-proxy.js'

// Early in application startup
setupProxy()
setupProxy() should be called before making any HTTP requests to ensure all clients are configured.

Testing Proxy Configuration

Local Testing

Test proxy configuration locally:
1

Set the HTTP_PROXY environment variable

export HTTP_PROXY=http://localhost:8888
2

Start a local proxy (optional)

Use a tool like mitmproxy or Charles Proxy to inspect traffic:
mitmproxy --listen-port 8888
3

Start the application

npm run dev
You should see the log message:
setting up global proxies
4

Make HTTP requests

Trigger API endpoints that make external requests. Monitor the proxy to verify traffic is routed correctly.

Verify Proxy Usage

Check application logs for proxy setup confirmation:
{
  "level": "info",
  "msg": "setting up global proxies"
}

Troubleshooting

Proxy Not Working

If external requests fail or don’t route through the proxy, verify:
  1. HTTP_PROXY environment variable is set correctly
  2. The proxy URL is accessible from the application
  3. The HTTP client you’re using supports the proxy configuration
Check configuration:
import { config } from './config.js'

console.log('Proxy URL:', config.get('httpProxy'))

Client-Specific Issues

Node Fetch: Must manually pass dispatcher option (see example above) Axios/Request: Should work via global-agent automatically Undici: Should work via setGlobalDispatcher automatically

Connection Timeouts

Adjust proxy agent timeout settings:
const proxyAgent = new ProxyAgent({
  uri: proxyUrl,
  keepAliveTimeout: 30,      // Increase timeout
  keepAliveMaxTimeout: 30
})

Best Practices

Recommendations for proxy usage:
  1. Use undici for new code - it has the best proxy support
  2. Call setupProxy() early in application startup
  3. Test proxy configuration in all environments
  4. Monitor logs to confirm proxy setup
  5. Use connection pooling and keep-alive for better performance

CDP Environment Configuration

In CDP environments, the HTTP_PROXY variable is typically set automatically:
# Example CDP configuration
export HTTP_PROXY=http://cdp-proxy.internal:3128
No additional configuration is required beyond ensuring the environment variable is set. See the Configuration page for all proxy-related settings.

Next Steps

Configuration

View all configuration options

Testing

Learn how to test the application

Build docs developers (and LLMs) love