<commit_before>const httpProxy = require('http-proxy');
const fs = require('fs');
const ProxyAgent = require('proxy-agent');
const logger = require('../../logger').policy;
const strategies = require('./strategies');

const createStrategy = (strategy, proxyOptions, endpointUrls) => {
  const Strategy = strategies[strategy];
  return new Strategy(proxyOptions, endpointUrls);
};

module.exports = function (params, config) {
  const serviceEndpointKey = params.serviceEndpoint;
  const endpoint = config.gatewayConfig.serviceEndpoints[serviceEndpointKey];

  if (!endpoint) { // Note: one day this can be ensured by JSON Schema, when $data keyword will be avaiable.
    throw new Error(`service endpoint ${serviceEndpointKey} (referenced in 'proxy' policy configuration) does not exist`);
  }

  const proxyOptions = parseProxyOptions(params.proxyOptions, endpoint);
  const proxy = httpProxy.createProxyServer({ changeOrigin: params.changeOrigin });

  proxy.on('error', (err, req, res) => {
    logger.warn(err);

    if (!res.headersSent) {
      res.status(502).send('Bad gateway.');
    } else {
      res.end();
    }
  });

  let strategy;
  let urls;

  if (endpoint.url) {
    strategy = 'static';
    urls = [endpoint.url];
  } else {
    strategy = params.strategy || 'round-robin';
    urls = endpoint.urls;
  }

  const balancer = createStrategy(strategy, proxyOptions, urls);

  const intermediateProxySettings = process.env.HTTP_PROXY || params.proxyUrl;

  if (intermediateProxySettings) {
    logger.debug(`using intermediate proxy ${intermediateProxySettings}`);
    proxyOptions.agent = new ProxyAgent(intermediateProxySettings);
  }

  return function proxyHandler (req, res) {
    const targetUrl = balancer.nextTarget();
    proxyOptions.target = Object.assign(proxyOptions.target, targetUrl);

    logger.debug(`proxying to ${targetUrl.href}, ${req.method} ${req.url}`);

    prepareHeaders(params, proxyOptions, req.egContext);
    proxy.web(req, res, proxyOptions);
  };

  // multiple urls will load balance, defaulting to round-robin
};

function prepareHeaders (params, proxyOptions, egContext) {
  proxyOptions.headers = proxyOptions.headers || {};
  // Default headers always sent to downstream
  // TODO: allow configuration
  if (egContext.requestId) {<commit_msg>Rename intermediateProxy parameter<commit_after>const httpProxy = require('http-proxy');
const fs = require('fs');
const ProxyAgent = require('proxy-agent');
const logger = require('../../logger').policy;
const strategies = require('./strategies');

const createStrategy = (strategy, proxyOptions, endpointUrls) => {
  const Strategy = strategies[strategy];
  return new Strategy(proxyOptions, endpointUrls);
};

module.exports = function (params, config) {
  const serviceEndpointKey = params.serviceEndpoint;
  const endpoint = config.gatewayConfig.serviceEndpoints[serviceEndpointKey];

  if (!endpoint) { // Note: one day this can be ensured by JSON Schema, when $data keyword will be avaiable.
    throw new Error(`service endpoint ${serviceEndpointKey} (referenced in 'proxy' policy configuration) does not exist`);
  }

  const proxyOptions = parseProxyOptions(params.proxyOptions, endpoint);
  const proxy = httpProxy.createProxyServer({ changeOrigin: params.changeOrigin });

  proxy.on('error', (err, req, res) => {
    logger.warn(err);

    if (!res.headersSent) {
      res.status(502).send('Bad gateway.');
    } else {
      res.end();
    }
  });

  let strategy;
  let urls;

  if (endpoint.url) {
    strategy = 'static';
    urls = [endpoint.url];
  } else {
    strategy = params.strategy || 'round-robin';
    urls = endpoint.urls;
  }

  const balancer = createStrategy(strategy, proxyOptions, urls);

  const intermediateProxyUrl = process.env.HTTP_PROXY || params.proxyUrl;

  if (intermediateProxyUrl) {
    logger.debug(`using intermediate proxy ${intermediateProxyUrl}`);
    proxyOptions.agent = new ProxyAgent(intermediateProxyUrl);
  }

  return function proxyHandler (req, res) {
    const targetUrl = balancer.nextTarget();
    proxyOptions.target = Object.assign(proxyOptions.target, targetUrl);

    logger.debug(`proxying to ${targetUrl.href}, ${req.method} ${req.url}`);

    prepareHeaders(params, proxyOptions, req.egContext);
    proxy.web(req, res, proxyOptions);
  };

  // multiple urls will load balance, defaulting to round-robin
};

function prepareHeaders (params, proxyOptions, egContext) {
  proxyOptions.headers = proxyOptions.headers || {};
  // Default headers always sent to downstream
  // TODO: allow configuration
  if (egContext.requestId) {
{'fraction_non_alphanumeric': 0.1280209013716525, 'fraction_numerical': 0.0013063357282821686, 'mean_word_length': 4.3730994152046785, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1524544', 'n_tokens_mistral': 1321, 'n_tokens_neox': 1296, 'n_words': 342}