CoolFace
Apppublic

AK-21/Graphite-Industrial-Intelligence

sourceHugging Faceupdated 3mo agoView on Hugging Face
0likes
index.js209 linesDownload Raw Back to serve-static
1/*!2 * serve-static3 * Copyright(c) 2010 Sencha Inc.4 * Copyright(c) 2011 TJ Holowaychuk5 * Copyright(c) 2014-2016 Douglas Christopher Wilson6 * MIT Licensed7 */8 9'use strict'10 11/**12 * Module dependencies.13 * @private14 */15 16var encodeUrl = require('encodeurl')17var escapeHtml = require('escape-html')18var parseUrl = require('parseurl')19var resolve = require('path').resolve20var send = require('send')21var url = require('url')22 23/**24 * Module exports.25 * @public26 */27 28module.exports = serveStatic29 30/**31 * @param {string} root32 * @param {object} [options]33 * @return {function}34 * @public35 */36 37function serveStatic (root, options) {38  if (!root) {39    throw new TypeError('root path required')40  }41 42  if (typeof root !== 'string') {43    throw new TypeError('root path must be a string')44  }45 46  // copy options object47  var opts = Object.create(options || null)48 49  // fall-though50  var fallthrough = opts.fallthrough !== false51 52  // default redirect53  var redirect = opts.redirect !== false54 55  // headers listener56  var setHeaders = opts.setHeaders57 58  if (setHeaders && typeof setHeaders !== 'function') {59    throw new TypeError('option setHeaders must be function')60  }61 62  // setup options for send63  opts.maxage = opts.maxage || opts.maxAge || 064  opts.root = resolve(root)65 66  // construct directory listener67  var onDirectory = redirect68    ? createRedirectDirectoryListener()69    : createNotFoundDirectoryListener()70 71  return function serveStatic (req, res, next) {72    if (req.method !== 'GET' && req.method !== 'HEAD') {73      if (fallthrough) {74        return next()75      }76 77      // method not allowed78      res.statusCode = 40579      res.setHeader('Allow', 'GET, HEAD')80      res.setHeader('Content-Length', '0')81      res.end()82      return83    }84 85    var forwardError = !fallthrough86    var originalUrl = parseUrl.original(req)87    var path = parseUrl(req).pathname88 89    // make sure redirect occurs at mount90    if (path === '/' && originalUrl.pathname.substr(-1) !== '/') {91      path = ''92    }93 94    // create send stream95    var stream = send(req, path, opts)96 97    // add directory handler98    stream.on('directory', onDirectory)99 100    // add headers listener101    if (setHeaders) {102      stream.on('headers', setHeaders)103    }104 105    // add file listener for fallthrough106    if (fallthrough) {107      stream.on('file', function onFile () {108        // once file is determined, always forward error109        forwardError = true110      })111    }112 113    // forward errors114    stream.on('error', function error (err) {115      if (forwardError || !(err.statusCode < 500)) {116        next(err)117        return118      }119 120      next()121    })122 123    // pipe124    stream.pipe(res)125  }126}127 128/**129 * Collapse all leading slashes into a single slash130 * @private131 */132function collapseLeadingSlashes (str) {133  for (var i = 0; i < str.length; i++) {134    if (str.charCodeAt(i) !== 0x2f /* / */) {135      break136    }137  }138 139  return i > 1140    ? '/' + str.substr(i)141    : str142}143 144/**145 * Create a minimal HTML document.146 *147 * @param {string} title148 * @param {string} body149 * @private150 */151 152function createHtmlDocument (title, body) {153  return '<!DOCTYPE html>\n' +154    '<html lang="en">\n' +155    '<head>\n' +156    '<meta charset="utf-8">\n' +157    '<title>' + title + '</title>\n' +158    '</head>\n' +159    '<body>\n' +160    '<pre>' + body + '</pre>\n' +161    '</body>\n' +162    '</html>\n'163}164 165/**166 * Create a directory listener that just 404s.167 * @private168 */169 170function createNotFoundDirectoryListener () {171  return function notFound () {172    this.error(404)173  }174}175 176/**177 * Create a directory listener that performs a redirect.178 * @private179 */180 181function createRedirectDirectoryListener () {182  return function redirect (res) {183    if (this.hasTrailingSlash()) {184      this.error(404)185      return186    }187 188    // get original URL189    var originalUrl = parseUrl.original(this.req)190 191    // append trailing slash192    originalUrl.path = null193    originalUrl.pathname = collapseLeadingSlashes(originalUrl.pathname + '/')194 195    // reformat the URL196    var loc = encodeUrl(url.format(originalUrl))197    var doc = createHtmlDocument('Redirecting', 'Redirecting to ' + escapeHtml(loc))198 199    // send redirect response200    res.statusCode = 301201    res.setHeader('Content-Type', 'text/html; charset=UTF-8')202    res.setHeader('Content-Length', Buffer.byteLength(doc))203    res.setHeader('Content-Security-Policy', "default-src 'none'")204    res.setHeader('X-Content-Type-Options', 'nosniff')205    res.setHeader('Location', loc)206    res.end(doc)207  }208}209