<commit_before>const express = require('express');
const Rule = require('./rule.js');
const logger = require('./logger.js');
const Acme = require('./acme');
const http = require('http');
const https = require('https');
const config = require('rc')('lroxy', {
  email: '',
  httpPort: 8080,
  httpsPort: 8443,
  rules: [],
});

const app = express();
const rules = [];
for (const rule of config.rules) {
  rules.push(new Rule(rule));
}
const names = {};
for (const rule of rules) {
  names[rule.getFromHost()] = true;
}
delete names[config.commonName];

const acme = new Acme(config.email, config.commonName, Object.keys(names));

app.use((req, res, next) => {
  next();
  logger.info('Handled request.', {
    remoteAddress: req.connection.remoteAddress,
    method: req.method,
    referer: req.headers.referer,
    userAgent: req.headers['user-agent'],
    host: req.headers.host,
    url: req.url,
    statusCode: res.statusCode,
    proxyTo: res.proxyToAddress,
  });
});

app.get('/.well-known/acme-challenge/:token', (req, res) => {
  const challenge = acme.getChallenge(req.params.token);
  res.write(challenge);
  res.end();
});

app.use((req, res) => {
  if (!req.secure) {
    return res.redirect("https://" + req.headers.host + req.url);
  }

  for (const rule of rules) {
    if (rule.match(req)) {
      rule.handle(req, res);
      return;
    }
  }

  // By default, reply service unavaliable if there is no matching reverse
  // proxy rule.
  res.writeHead(503, 'Service Unavaliable');
  res.end('Service Unavaliable');
});

module.exports = async function() {
  http.createServer(app).listen(config.httpPort);
  logger.info(`lroxy (http) started on ${config.httpPort}.`);
  const sslInfo = await acme.run();
  https.createServer({
    key: sslInfo.key,
    cert: sslInfo.cert,
  }, app).listen(config.httpsPort);
  logger.info(`lroxy (https) started on ${config.httpsPort}.`);
};<commit_msg>Allow lroxy to run with HTTP only.<commit_after>const express = require('express');
const Rule = require('./rule.js');
const logger = require('./logger.js');
const Acme = require('./acme');
const http = require('http');
const https = require('https');
const config = require('rc')('lroxy', {
  email: null,
  commonName: null,
  httpPort: 8080,
  httpsPort: null,
  rules: [],
});

const app = express();
const rules = [];
for (const rule of config.rules) {
  rules.push(new Rule(rule));
}
const names = {};
for (const rule of rules) {
  names[rule.getFromHost()] = true;
}
delete names[config.commonName];

const acme = new Acme(config.email, config.commonName, Object.keys(names));

app.use((req, res, next) => {
  next();
  logger.info('Handled request.', {
    remoteAddress: req.connection.remoteAddress,
    method: req.method,
    referer: req.headers.referer,
    userAgent: req.headers['user-agent'],
    url: `${req.secure ? 'https' : 'http'}://${req.hostname}${req.url}`,
    statusCode: res.statusCode,
    proxyTo: res.proxyToAddress,
  });
});

app.get('/.well-known/acme-challenge/:token', (req, res) => {
  const challenge = acme.getChallenge(req.params.token);
  res.write(challenge);
  res.end();
});

app.use((req, res) => {
  if (config.httpsPort != null && !req.secure) {
    return res.redirect('https://' + req.headers.host + req.url);
  }

  for (const rule of rules) {
    if (rule.match(req)) {
      rule.handle(req, res);
      return;
    }
  }

  // By default, reply service unavaliable if there is no matching reverse
  // proxy rule.
  res.writeHead(503, 'Service Unavaliable');
  res.end('Service Unavaliable');
});

module.exports = async function() {
  http.createServer(app).listen(config.httpPort);
  logger.info(`lroxy (http) started on ${config.httpPort}.`);

  if (config.httpsPort != null) {
    const sslInfo = await acme.run();
    https.createServer({
      key: sslInfo.key,
      cert: sslInfo.cert,
    }, app).listen(config.httpsPort);
    logger.info(`lroxy (https) started on ${config.httpsPort}.`);
  }
};
{'fraction_non_alphanumeric': 0.18133669609079445, 'fraction_numerical': 0.004539722572509458, 'mean_word_length': 3.795646916565901, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 2, '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': '6554878', 'n_tokens_mistral': 1359, 'n_tokens_neox': 1338, 'n_words': 306}