Backend half
This commit is contained in:
+58
-10
@@ -17,12 +17,20 @@ 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
|
||||
|
||||
/**
|
||||
@@ -34,8 +42,8 @@ var isFinished = onFinished.isFinished
|
||||
|
||||
function createHtmlDocument (message) {
|
||||
var body = escapeHtml(message)
|
||||
.replaceAll('\n', '<br>')
|
||||
.replaceAll(' ', ' ')
|
||||
.replace(NEWLINE_REGEXP, '<br>')
|
||||
.replace(DOUBLE_SPACE_REGEXP, ' ')
|
||||
|
||||
return '<!DOCTYPE html>\n' +
|
||||
'<html lang="en">\n' +
|
||||
@@ -81,7 +89,7 @@ function finalhandler (req, res, options) {
|
||||
var status
|
||||
|
||||
// ignore 404 on in-flight response
|
||||
if (!err && res.headersSent) {
|
||||
if (!err && headersSent(res)) {
|
||||
debug('cannot 404 after headers sent')
|
||||
return
|
||||
}
|
||||
@@ -111,11 +119,11 @@ function finalhandler (req, res, options) {
|
||||
|
||||
// schedule onerror callback
|
||||
if (err && onerror) {
|
||||
setImmediate(onerror, err, req, res)
|
||||
defer(onerror, err, req, res)
|
||||
}
|
||||
|
||||
// cannot actually respond
|
||||
if (res.headersSent) {
|
||||
if (headersSent(res)) {
|
||||
debug('cannot %d after headers sent', status)
|
||||
if (req.socket) {
|
||||
req.socket.destroy()
|
||||
@@ -141,7 +149,15 @@ function getErrorHeaders (err) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return { ...err.headers }
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,6 +246,20 @@ function getResponseStatusCode (res) {
|
||||
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.
|
||||
*
|
||||
@@ -259,9 +289,7 @@ function send (req, res, status, headers, message) {
|
||||
res.removeHeader('Content-Range')
|
||||
|
||||
// response headers
|
||||
for (const [key, value] of Object.entries(headers ?? {})) {
|
||||
res.setHeader(key, value)
|
||||
}
|
||||
setHeaders(res, headers)
|
||||
|
||||
// security headers
|
||||
res.setHeader('Content-Security-Policy', "default-src 'none'")
|
||||
@@ -285,9 +313,29 @@ function send (req, res, status, headers, message) {
|
||||
}
|
||||
|
||||
// unpipe everything from the request
|
||||
req.unpipe()
|
||||
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