<commit_before>// Native
const path = require('path')
const { parse, format } = require('url')

// Packages
const micro = require('micro')
const auth = require('basic-auth')
const { red } = require('chalk')
const fs = require('fs-extra')
const pathType = require('path-type')
const mime = require('mime-types')
const stream = require('send')
const { coroutine } = require('bluebird')

// Ours
const renderDirectory = require('./render')

module.exports = coroutine(function*(req, res, flags, current, ignoredFiles) {
  const headers = {}

  if (flags.cors) {
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Headers'] =
      'Origin, X-Requested-With, Content-Type, Accept, Range'
  }

  for (const header in headers) {
    if (!{}.hasOwnProperty.call(headers, header)) {
      continue
    }

    res.setHeader(header, headers[header])
  }

  if (flags.auth) {
    const credentials = auth(req)

    if (!process.env.SERVE_USER || !process.env.SERVE_PASSWORD) {
      console.error(
        red(
          'You are running serve with basic auth but did not set the SERVE_USER and SERVE_PASSWORD environment variables.'
        )
      )

      // eslint-disable-next-line unicorn/no-process-exit
      process.exit(1)
    }

    if (
      !credentials ||
      credentials.name !== process.env.SERVE_USER ||
      credentials.pass !== process.env.SERVE_PASSWORD
    ) {
      res.statusCode = 401
      res.setHeader('WWW-Authenticate', 'Basic realm="User Visible Realm"')
      return micro.send(res, 401, 'Access Denied')
    }
  }

  const { pathname } = parse(req.url)
  const assetDir = path.normalize(process.env.ASSET_DIR)

  let related = path.parse(path.join(current, pathname))
  let assetRequest = false

  if (related.dir.indexOf(assetDir) > -1) {
    assetRequest = true
    const relative = path.relative(assetDir, pathname)
    related = path.parse(path.join(__dirname, '/../assets', relative))
  }

  related = decodeURIComponent(path.format(related))
  let notFoundResponse = 'Not Found'

  try {
    const custom404Path = path.join(current, '/404.html')
    notFoundResponse = yield fs.readFile(custom404Path, 'utf-8')
  } catch (err) {}

  // Don't allow rendering ignored files
  const ignored = !ignoredFiles.every(item => {
    return !pathname.includes(item)
  })

  if (ignored || (!assetRequest && related.indexOf(current) !== 0)) {
    return micro.send(res, 404, notFoundResponse)
  }

  const relatedExists = yield fs.exists(related)

  if (!relatedExists && flags.single === undefined) {
    return micro.send(res, 404, notFoundResponse)
  }

  const streamOptions = {}

  if (flags.cache) {
    streamOptions.maxAge = flags.cache
  } else if (flags.single) {<commit_msg>Fixed custom 404 pages (#218)<commit_after>// Native
const path = require('path')
const { parse, format } = require('url')

// Packages
const micro = require('micro')
const auth = require('basic-auth')
const { red } = require('chalk')
const fs = require('fs-extra')
const pathType = require('path-type')
const mime = require('mime-types')
const stream = require('send')
const { coroutine } = require('bluebird')

// Ours
const renderDirectory = require('./render')

module.exports = coroutine(function*(req, res, flags, current, ignoredFiles) {
  const headers = {}

  if (flags.cors) {
    headers['Access-Control-Allow-Origin'] = '*'
    headers['Access-Control-Allow-Headers'] =
      'Origin, X-Requested-With, Content-Type, Accept, Range'
  }

  for (const header in headers) {
    if (!{}.hasOwnProperty.call(headers, header)) {
      continue
    }

    res.setHeader(header, headers[header])
  }

  if (flags.auth) {
    const credentials = auth(req)

    if (!process.env.SERVE_USER || !process.env.SERVE_PASSWORD) {
      console.error(
        red(
          'You are running serve with basic auth but did not set the SERVE_USER and SERVE_PASSWORD environment variables.'
        )
      )

      // eslint-disable-next-line unicorn/no-process-exit
      process.exit(1)
    }

    if (
      !credentials ||
      credentials.name !== process.env.SERVE_USER ||
      credentials.pass !== process.env.SERVE_PASSWORD
    ) {
      res.statusCode = 401
      res.setHeader('WWW-Authenticate', 'Basic realm="User Visible Realm"')
      return micro.send(res, 401, 'Access Denied')
    }
  }

  const { pathname } = parse(req.url)
  const assetDir = path.normalize(process.env.ASSET_DIR)

  let related = path.parse(path.join(current, pathname))
  let assetRequest = false

  if (related.dir.indexOf(assetDir) > -1) {
    assetRequest = true
    const relative = path.relative(assetDir, pathname)
    related = path.parse(path.join(__dirname, '/../assets', relative))
  }

  related = decodeURIComponent(path.format(related))
  let notFoundResponse = 'Not Found'

  try {
    const custom404Path = path.join(current, '/404.html')
    notFoundResponse = yield fs.readFile(custom404Path, 'utf-8')
  } catch (err) {}

  // Don't allow rendering ignored files
  const ignored = !ignoredFiles.every(item => {
    return !pathname.includes(item)
  })

  if (ignored || (!assetRequest && related.indexOf(current) !== 0)) {
    return micro.send(res, 404, notFoundResponse)
  }

  const relatedExists = yield fs.exists(related)

  if (!relatedExists && !flags.single) {
    return micro.send(res, 404, notFoundResponse)
  }

  const streamOptions = {}

  if (flags.cache) {
    streamOptions.maxAge = flags.cache
  } else if (flags.single) {
{'fraction_non_alphanumeric': 0.14040533138579514, 'fraction_numerical': 0.010224575497535146, 'mean_word_length': 3.351072279586974, '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': '3983514', 'n_tokens_mistral': 1780, 'n_tokens_neox': 1700, 'n_words': 397}