.
This commit is contained in:
		
							
								
								
									
										341
									
								
								qwen/nodejs/node_modules/finalhandler/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								qwen/nodejs/node_modules/finalhandler/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,341 @@
 | 
			
		||||
/*!
 | 
			
		||||
 * finalhandler
 | 
			
		||||
 * Copyright(c) 2014-2022 Douglas Christopher Wilson
 | 
			
		||||
 * MIT Licensed
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
'use strict'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Module dependencies.
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var debug = require('debug')('finalhandler')
 | 
			
		||||
var encodeUrl = require('encodeurl')
 | 
			
		||||
var escapeHtml = require('escape-html')
 | 
			
		||||
var onFinished = require('on-finished')
 | 
			
		||||
var parseUrl = require('parseurl')
 | 
			
		||||
var statuses = require('statuses')
 | 
			
		||||
var unpipe = require('unpipe')
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Module variables.
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
var DOUBLE_SPACE_REGEXP = /\x20{2}/g
 | 
			
		||||
var NEWLINE_REGEXP = /\n/g
 | 
			
		||||
 | 
			
		||||
/* istanbul ignore next */
 | 
			
		||||
var defer = typeof setImmediate === 'function'
 | 
			
		||||
  ? setImmediate
 | 
			
		||||
  : function (fn) { process.nextTick(fn.bind.apply(fn, arguments)) }
 | 
			
		||||
var isFinished = onFinished.isFinished
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a minimal HTML document.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {string} message
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function createHtmlDocument (message) {
 | 
			
		||||
  var body = escapeHtml(message)
 | 
			
		||||
    .replace(NEWLINE_REGEXP, '<br>')
 | 
			
		||||
    .replace(DOUBLE_SPACE_REGEXP, '  ')
 | 
			
		||||
 | 
			
		||||
  return '<!DOCTYPE html>\n' +
 | 
			
		||||
    '<html lang="en">\n' +
 | 
			
		||||
    '<head>\n' +
 | 
			
		||||
    '<meta charset="utf-8">\n' +
 | 
			
		||||
    '<title>Error</title>\n' +
 | 
			
		||||
    '</head>\n' +
 | 
			
		||||
    '<body>\n' +
 | 
			
		||||
    '<pre>' + body + '</pre>\n' +
 | 
			
		||||
    '</body>\n' +
 | 
			
		||||
    '</html>\n'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Module exports.
 | 
			
		||||
 * @public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
module.exports = finalhandler
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a function to handle the final response.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Request} req
 | 
			
		||||
 * @param {Response} res
 | 
			
		||||
 * @param {Object} [options]
 | 
			
		||||
 * @return {Function}
 | 
			
		||||
 * @public
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function finalhandler (req, res, options) {
 | 
			
		||||
  var opts = options || {}
 | 
			
		||||
 | 
			
		||||
  // get environment
 | 
			
		||||
  var env = opts.env || process.env.NODE_ENV || 'development'
 | 
			
		||||
 | 
			
		||||
  // get error callback
 | 
			
		||||
  var onerror = opts.onerror
 | 
			
		||||
 | 
			
		||||
  return function (err) {
 | 
			
		||||
    var headers
 | 
			
		||||
    var msg
 | 
			
		||||
    var status
 | 
			
		||||
 | 
			
		||||
    // ignore 404 on in-flight response
 | 
			
		||||
    if (!err && headersSent(res)) {
 | 
			
		||||
      debug('cannot 404 after headers sent')
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // unhandled error
 | 
			
		||||
    if (err) {
 | 
			
		||||
      // respect status code from error
 | 
			
		||||
      status = getErrorStatusCode(err)
 | 
			
		||||
 | 
			
		||||
      if (status === undefined) {
 | 
			
		||||
        // fallback to status code on response
 | 
			
		||||
        status = getResponseStatusCode(res)
 | 
			
		||||
      } else {
 | 
			
		||||
        // respect headers from error
 | 
			
		||||
        headers = getErrorHeaders(err)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // get error message
 | 
			
		||||
      msg = getErrorMessage(err, status, env)
 | 
			
		||||
    } else {
 | 
			
		||||
      // not found
 | 
			
		||||
      status = 404
 | 
			
		||||
      msg = 'Cannot ' + req.method + ' ' + encodeUrl(getResourceName(req))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    debug('default %s', status)
 | 
			
		||||
 | 
			
		||||
    // schedule onerror callback
 | 
			
		||||
    if (err && onerror) {
 | 
			
		||||
      defer(onerror, err, req, res)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // cannot actually respond
 | 
			
		||||
    if (headersSent(res)) {
 | 
			
		||||
      debug('cannot %d after headers sent', status)
 | 
			
		||||
      if (req.socket) {
 | 
			
		||||
        req.socket.destroy()
 | 
			
		||||
      }
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // send response
 | 
			
		||||
    send(req, res, status, headers, msg)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get headers from Error object.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Error} err
 | 
			
		||||
 * @return {object}
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function getErrorHeaders (err) {
 | 
			
		||||
  if (!err.headers || typeof err.headers !== 'object') {
 | 
			
		||||
    return undefined
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var headers = Object.create(null)
 | 
			
		||||
  var keys = Object.keys(err.headers)
 | 
			
		||||
 | 
			
		||||
  for (var i = 0; i < keys.length; i++) {
 | 
			
		||||
    var key = keys[i]
 | 
			
		||||
    headers[key] = err.headers[key]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return headers
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get message from Error object, fallback to status message.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Error} err
 | 
			
		||||
 * @param {number} status
 | 
			
		||||
 * @param {string} env
 | 
			
		||||
 * @return {string}
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function getErrorMessage (err, status, env) {
 | 
			
		||||
  var msg
 | 
			
		||||
 | 
			
		||||
  if (env !== 'production') {
 | 
			
		||||
    // use err.stack, which typically includes err.message
 | 
			
		||||
    msg = err.stack
 | 
			
		||||
 | 
			
		||||
    // fallback to err.toString() when possible
 | 
			
		||||
    if (!msg && typeof err.toString === 'function') {
 | 
			
		||||
      msg = err.toString()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return msg || statuses.message[status]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get status code from Error object.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Error} err
 | 
			
		||||
 * @return {number}
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function getErrorStatusCode (err) {
 | 
			
		||||
  // check err.status
 | 
			
		||||
  if (typeof err.status === 'number' && err.status >= 400 && err.status < 600) {
 | 
			
		||||
    return err.status
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // check err.statusCode
 | 
			
		||||
  if (typeof err.statusCode === 'number' && err.statusCode >= 400 && err.statusCode < 600) {
 | 
			
		||||
    return err.statusCode
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return undefined
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get resource name for the request.
 | 
			
		||||
 *
 | 
			
		||||
 * This is typically just the original pathname of the request
 | 
			
		||||
 * but will fallback to "resource" is that cannot be determined.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {IncomingMessage} req
 | 
			
		||||
 * @return {string}
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function getResourceName (req) {
 | 
			
		||||
  try {
 | 
			
		||||
    return parseUrl.original(req).pathname
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    return 'resource'
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get status code from response.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {OutgoingMessage} res
 | 
			
		||||
 * @return {number}
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function getResponseStatusCode (res) {
 | 
			
		||||
  var status = res.statusCode
 | 
			
		||||
 | 
			
		||||
  // default status code to 500 if outside valid range
 | 
			
		||||
  if (typeof status !== 'number' || status < 400 || status > 599) {
 | 
			
		||||
    status = 500
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return status
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Determine if the response headers have been sent.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {object} res
 | 
			
		||||
 * @returns {boolean}
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function headersSent (res) {
 | 
			
		||||
  return typeof res.headersSent !== 'boolean'
 | 
			
		||||
    ? Boolean(res._header)
 | 
			
		||||
    : res.headersSent
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Send response.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {IncomingMessage} req
 | 
			
		||||
 * @param {OutgoingMessage} res
 | 
			
		||||
 * @param {number} status
 | 
			
		||||
 * @param {object} headers
 | 
			
		||||
 * @param {string} message
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function send (req, res, status, headers, message) {
 | 
			
		||||
  function write () {
 | 
			
		||||
    // response body
 | 
			
		||||
    var body = createHtmlDocument(message)
 | 
			
		||||
 | 
			
		||||
    // response status
 | 
			
		||||
    res.statusCode = status
 | 
			
		||||
 | 
			
		||||
    if (req.httpVersionMajor < 2) {
 | 
			
		||||
      res.statusMessage = statuses.message[status]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // remove any content headers
 | 
			
		||||
    res.removeHeader('Content-Encoding')
 | 
			
		||||
    res.removeHeader('Content-Language')
 | 
			
		||||
    res.removeHeader('Content-Range')
 | 
			
		||||
 | 
			
		||||
    // response headers
 | 
			
		||||
    setHeaders(res, headers)
 | 
			
		||||
 | 
			
		||||
    // security headers
 | 
			
		||||
    res.setHeader('Content-Security-Policy', "default-src 'none'")
 | 
			
		||||
    res.setHeader('X-Content-Type-Options', 'nosniff')
 | 
			
		||||
 | 
			
		||||
    // standard headers
 | 
			
		||||
    res.setHeader('Content-Type', 'text/html; charset=utf-8')
 | 
			
		||||
    res.setHeader('Content-Length', Buffer.byteLength(body, 'utf8'))
 | 
			
		||||
 | 
			
		||||
    if (req.method === 'HEAD') {
 | 
			
		||||
      res.end()
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    res.end(body, 'utf8')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (isFinished(req)) {
 | 
			
		||||
    write()
 | 
			
		||||
    return
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // unpipe everything from the request
 | 
			
		||||
  unpipe(req)
 | 
			
		||||
 | 
			
		||||
  // flush the request
 | 
			
		||||
  onFinished(req, write)
 | 
			
		||||
  req.resume()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set response headers from an object.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {OutgoingMessage} res
 | 
			
		||||
 * @param {object} headers
 | 
			
		||||
 * @private
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function setHeaders (res, headers) {
 | 
			
		||||
  if (!headers) {
 | 
			
		||||
    return
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var keys = Object.keys(headers)
 | 
			
		||||
  for (var i = 0; i < keys.length; i++) {
 | 
			
		||||
    var key = keys[i]
 | 
			
		||||
    res.setHeader(key, headers[key])
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user