CoolFace
Apppublic

opusdev/vector-similarity-api

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes
index.js342 linesDownload Raw Back to finalhandler
1/*!2 * finalhandler3 * Copyright(c) 2014-2022 Douglas Christopher Wilson4 * MIT Licensed5 */6 7'use strict'8 9/**10 * Module dependencies.11 * @private12 */13 14var debug = require('debug')('finalhandler')15var encodeUrl = require('encodeurl')16var escapeHtml = require('escape-html')17var onFinished = require('on-finished')18var parseUrl = require('parseurl')19var statuses = require('statuses')20var unpipe = require('unpipe')21 22/**23 * Module variables.24 * @private25 */26 27var DOUBLE_SPACE_REGEXP = /\x20{2}/g28var NEWLINE_REGEXP = /\n/g29 30/* istanbul ignore next */31var defer = typeof setImmediate === 'function'32  ? setImmediate33  : function (fn) { process.nextTick(fn.bind.apply(fn, arguments)) }34var isFinished = onFinished.isFinished35 36/**37 * Create a minimal HTML document.38 *39 * @param {string} message40 * @private41 */42 43function createHtmlDocument (message) {44  var body = escapeHtml(message)45    .replace(NEWLINE_REGEXP, '<br>')46    .replace(DOUBLE_SPACE_REGEXP, ' &nbsp;')47 48  return '<!DOCTYPE html>\n' +49    '<html lang="en">\n' +50    '<head>\n' +51    '<meta charset="utf-8">\n' +52    '<title>Error</title>\n' +53    '</head>\n' +54    '<body>\n' +55    '<pre>' + body + '</pre>\n' +56    '</body>\n' +57    '</html>\n'58}59 60/**61 * Module exports.62 * @public63 */64 65module.exports = finalhandler66 67/**68 * Create a function to handle the final response.69 *70 * @param {Request} req71 * @param {Response} res72 * @param {Object} [options]73 * @return {Function}74 * @public75 */76 77function finalhandler (req, res, options) {78  var opts = options || {}79 80  // get environment81  var env = opts.env || process.env.NODE_ENV || 'development'82 83  // get error callback84  var onerror = opts.onerror85 86  return function (err) {87    var headers88    var msg89    var status90 91    // ignore 404 on in-flight response92    if (!err && headersSent(res)) {93      debug('cannot 404 after headers sent')94      return95    }96 97    // unhandled error98    if (err) {99      // respect status code from error100      status = getErrorStatusCode(err)101 102      if (status === undefined) {103        // fallback to status code on response104        status = getResponseStatusCode(res)105      } else {106        // respect headers from error107        headers = getErrorHeaders(err)108      }109 110      // get error message111      msg = getErrorMessage(err, status, env)112    } else {113      // not found114      status = 404115      msg = 'Cannot ' + req.method + ' ' + encodeUrl(getResourceName(req))116    }117 118    debug('default %s', status)119 120    // schedule onerror callback121    if (err && onerror) {122      defer(onerror, err, req, res)123    }124 125    // cannot actually respond126    if (headersSent(res)) {127      debug('cannot %d after headers sent', status)128      if (req.socket) {129        req.socket.destroy()130      }131      return132    }133 134    // send response135    send(req, res, status, headers, msg)136  }137}138 139/**140 * Get headers from Error object.141 *142 * @param {Error} err143 * @return {object}144 * @private145 */146 147function getErrorHeaders (err) {148  if (!err.headers || typeof err.headers !== 'object') {149    return undefined150  }151 152  var headers = Object.create(null)153  var keys = Object.keys(err.headers)154 155  for (var i = 0; i < keys.length; i++) {156    var key = keys[i]157    headers[key] = err.headers[key]158  }159 160  return headers161}162 163/**164 * Get message from Error object, fallback to status message.165 *166 * @param {Error} err167 * @param {number} status168 * @param {string} env169 * @return {string}170 * @private171 */172 173function getErrorMessage (err, status, env) {174  var msg175 176  if (env !== 'production') {177    // use err.stack, which typically includes err.message178    msg = err.stack179 180    // fallback to err.toString() when possible181    if (!msg && typeof err.toString === 'function') {182      msg = err.toString()183    }184  }185 186  return msg || statuses.message[status]187}188 189/**190 * Get status code from Error object.191 *192 * @param {Error} err193 * @return {number}194 * @private195 */196 197function getErrorStatusCode (err) {198  // check err.status199  if (typeof err.status === 'number' && err.status >= 400 && err.status < 600) {200    return err.status201  }202 203  // check err.statusCode204  if (typeof err.statusCode === 'number' && err.statusCode >= 400 && err.statusCode < 600) {205    return err.statusCode206  }207 208  return undefined209}210 211/**212 * Get resource name for the request.213 *214 * This is typically just the original pathname of the request215 * but will fallback to "resource" is that cannot be determined.216 *217 * @param {IncomingMessage} req218 * @return {string}219 * @private220 */221 222function getResourceName (req) {223  try {224    return parseUrl.original(req).pathname225  } catch (e) {226    return 'resource'227  }228}229 230/**231 * Get status code from response.232 *233 * @param {OutgoingMessage} res234 * @return {number}235 * @private236 */237 238function getResponseStatusCode (res) {239  var status = res.statusCode240 241  // default status code to 500 if outside valid range242  if (typeof status !== 'number' || status < 400 || status > 599) {243    status = 500244  }245 246  return status247}248 249/**250 * Determine if the response headers have been sent.251 *252 * @param {object} res253 * @returns {boolean}254 * @private255 */256 257function headersSent (res) {258  return typeof res.headersSent !== 'boolean'259    ? Boolean(res._header)260    : res.headersSent261}262 263/**264 * Send response.265 *266 * @param {IncomingMessage} req267 * @param {OutgoingMessage} res268 * @param {number} status269 * @param {object} headers270 * @param {string} message271 * @private272 */273 274function send (req, res, status, headers, message) {275  function write () {276    // response body277    var body = createHtmlDocument(message)278 279    // response status280    res.statusCode = status281 282    if (req.httpVersionMajor < 2) {283      res.statusMessage = statuses.message[status]284    }285 286    // remove any content headers287    res.removeHeader('Content-Encoding')288    res.removeHeader('Content-Language')289    res.removeHeader('Content-Range')290 291    // response headers292    setHeaders(res, headers)293 294    // security headers295    res.setHeader('Content-Security-Policy', "default-src 'none'")296    res.setHeader('X-Content-Type-Options', 'nosniff')297 298    // standard headers299    res.setHeader('Content-Type', 'text/html; charset=utf-8')300    res.setHeader('Content-Length', Buffer.byteLength(body, 'utf8'))301 302    if (req.method === 'HEAD') {303      res.end()304      return305    }306 307    res.end(body, 'utf8')308  }309 310  if (isFinished(req)) {311    write()312    return313  }314 315  // unpipe everything from the request316  unpipe(req)317 318  // flush the request319  onFinished(req, write)320  req.resume()321}322 323/**324 * Set response headers from an object.325 *326 * @param {OutgoingMessage} res327 * @param {object} headers328 * @private329 */330 331function setHeaders (res, headers) {332  if (!headers) {333    return334  }335 336  var keys = Object.keys(headers)337  for (var i = 0; i < keys.length; i++) {338    var key = keys[i]339    res.setHeader(key, headers[key])340  }341}342