<commit_before>const { exec } = require('child_process');
const { createWriteStream } = require('fs');
const { createServer } = require('http');
const { parse } = require('url');
const { resolve } = require('path');
const { createProxy } = require('http-proxy');
const cloneDeep = require('lodash.clonedeep');
const exitHook = require('async-exit-hook');
const sleep = require('async-sleep');

const { getPortByPid, findRule, kill } = require('./utils');

const allHTTPMethods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE'];

const run = async (rule, cwd) => {
  cwd = cwd || process.cwd();

  // Trying to prevent port conflicts.
  await sleep.randomResolve(0, 500);
  const proc = exec(rule.run, {
    env: Object.assign(process.env, rule.env || {}),
    cwd: resolve(cwd)
  }, (err) => {
    if (err)  {
      console.error(rule.pathname, err);
    }
  });

  if (rule.debug) {
    if (typeof rule.debug === 'boolean' || (typeof rule.debug === 'object' && rule.debug.stdout === true)) {
      proc.stdout.pipe(process.stdout);
    }

    if (typeof rule.debug === 'boolean' || (typeof rule.debug === 'object' && rule.debug.stderr === true)) {
      proc.stderr.pipe(process.stderr);
    }
  }

  if (rule.logFile) {
    const writeStream = createWriteStream(rule.logFile);
    proc.stdout.pipe(writeStream);
    proc.stderr.pipe(writeStream);
    rule.writeStream = writeStream;
  }

  try {
    rule.proc = proc;
    rule.port = rule.port || await getPortByPid(proc.pid);
    return rule;
  } catch (err) {
    throw err;
  }

};

const createRequestListner = (rules, options, proxy) => {
  return (req, res) => {
    const { pathname } = parse(req.url);
    const rule = findRule({
      rules,
      host: req.headers.host,
      port: options.port,
      pathname,
      method: req.method
    });

    if (!rule) {
      res.writeHead(404);
      return res.end('Not Found');
    }

    if (!rule.port) {
      res.writeHead(503);
      return res.end('Service Unavailable');
    }

    const host = options.host || 'localhost';

    if (rule.proxy) {
      req.headers.host = parse(rule.proxy).hostname;
    }

    const target = rule.proxy || {
      host,
      port: rule.port
    };

    proxy.web(req, res, {
      target
    }, err => {
      console.error(rule.pathname, err);
      res.writeHead(500);
      res.end('Internal Server Error');
    });

  };
};

module.exports = options => {
  const rules = cloneDeep(options.rules);

  const killChilds = async ({ exitParent }) => {
    const results = [];
    for (const rule of rules) {
      if (rule.writeStream) {
        rule.writeStream.end();
      }

      if (rule.proc) {<commit_msg>prevent printing errors when gateway shutting down<commit_after>const { exec } = require('child_process');
const { createWriteStream } = require('fs');
const { createServer } = require('http');
const { parse } = require('url');
const { resolve } = require('path');
const { createProxy } = require('http-proxy');
const cloneDeep = require('lodash.clonedeep');
const exitHook = require('async-exit-hook');
const sleep = require('async-sleep');

const { getPortByPid, findRule, kill } = require('./utils');

const allHTTPMethods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE'];

let isShuttingDown = false;
const run = async (rule, cwd) => {
  cwd = cwd || process.cwd();

  // Trying to prevent port conflicts.
  await sleep.randomResolve(0, 500);
  const proc = exec(rule.run, {
    env: Object.assign(process.env, rule.env || {}),
    cwd: resolve(cwd)
  }, (err) => {
    if (err && !isShuttingDown)  {
      console.error(rule.pathname, err);
    }
  });

  if (rule.debug) {
    if (typeof rule.debug === 'boolean' || (typeof rule.debug === 'object' && rule.debug.stdout === true)) {
      proc.stdout.pipe(process.stdout);
    }

    if (typeof rule.debug === 'boolean' || (typeof rule.debug === 'object' && rule.debug.stderr === true)) {
      proc.stderr.pipe(process.stderr);
    }
  }

  if (rule.logFile) {
    const writeStream = createWriteStream(rule.logFile);
    proc.stdout.pipe(writeStream);
    proc.stderr.pipe(writeStream);
    rule.writeStream = writeStream;
  }

  try {
    rule.proc = proc;
    rule.port = rule.port || await getPortByPid(proc.pid);
    return rule;
  } catch (err) {
    throw err;
  }

};

const createRequestListner = (rules, options, proxy) => {
  return (req, res) => {
    const { pathname } = parse(req.url);
    const rule = findRule({
      rules,
      host: req.headers.host,
      port: options.port,
      pathname,
      method: req.method
    });

    if (!rule) {
      res.writeHead(404);
      return res.end('Not Found');
    }

    if (!rule.port) {
      res.writeHead(503);
      return res.end('Service Unavailable');
    }

    const host = options.host || 'localhost';

    if (rule.proxy) {
      req.headers.host = parse(rule.proxy).hostname;
    }

    const target = rule.proxy || {
      host,
      port: rule.port
    };

    proxy.web(req, res, {
      target
    }, err => {
      console.error(rule.pathname, err);
      res.writeHead(500);
      res.end('Internal Server Error');
    });

  };
};

module.exports = options => {
  const rules = cloneDeep(options.rules);

  const killChilds = async ({ exitParent }) => {
    isShuttingDown = true;
    const results = [];
    for (const rule of rules) {
      if (rule.writeStream) {
        rule.writeStream.end();
      }

      if (rule.proc) {
{'fraction_non_alphanumeric': 0.16973564266180494, 'fraction_numerical': 0.004740200546946217, 'mean_word_length': 2.825662482566248, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, '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': '4171927', 'n_tokens_mistral': 1814, 'n_tokens_neox': 1766, 'n_words': 400}