Skip to content

Commit

Permalink
Merge pull request #8 from fyrejet/v2.3-
Browse files Browse the repository at this point in the history
V2.3.
  • Loading branch information
schamberg97 committed Nov 7, 2020
2 parents e5ba7a0 + 26af380 commit f012ff7
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 103 deletions.
5 changes: 2 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,8 @@ exports.response = res
// exports.Route = Route;
exports.Router = require('./lib/routing/request-router-constructor')

exports.uwsCompat = function() {
return require('low-http-server')
}

exports.uwsCompat = require('./lib/uwsCompat')

/**
* Replace Express removed middleware with an appropriate error message. We are not express, but we will imitate it precisely
Expand Down
36 changes: 18 additions & 18 deletions lib/middleware/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,38 @@ var init = function (options, reqProperties, reqPropertiesEssential, router, sla
}
})

function defErrHandlerBuilder (deh, res, req) {
function defErrHandlerBuilder (defaultErrHandler, res, req) {
return function (err) {
if (req.method !== 'OPTIONS') {
return deh(err)
return defaultErrHandler(err)
}
let options
if (router) options = router.getRouter().availableMethodsForRoute[req.url]
if (!options) options = req.app.getRouter().availableMethodsForRoute[req.url]
if (!options) {
return deh(err || false)
return defaultErrHandler(err || false)
}
const optionsString = options.join(',')
this.setHeader('Allow', optionsString)
return this.status(200).send(optionsString)
}
}

var init = async (req, res, next) => { // this function actually enables all the express-like kinkiness ;)
const deh = res.defaultErrHandler
let normInit = async (req, res, next) => { // this function actually enables all the express-like kinkiness ;)
const deh = res.defaultErrHandler // backup of defaultErrHandler
res.defaultErrHandler = defErrHandlerBuilder(deh, res, req)
req.activateExpress = function() {
let req = this
let res = this.res
Object.keys(req.app.response).forEach(key => {
res[key] = req.app.response[key]
})
Object.keys(req.app.request).forEach(key => {
req[key] = req.app.request[key]
})
// Object.assign is supposed to be faster, BUT Google's V8 begs to differ, with forEach usually being at least 5% faster
// Object.assign(req, req.app.request)
// Object.assign(res, req.app.response)

Object.assign(req, req.app.request)
Object.assign(res, req.app.response)

/*
this previously had a ' Object.keys(req.app.response).forEach(key => { ' implementation that sucked and an erroneous claim that it was faster
due to erroneous benchmarks. I am sorry, my dudes
*/

Object.defineProperties(req, reqProperties)
return req
}
Expand All @@ -61,7 +61,7 @@ var init = function (options, reqProperties, reqPropertiesEssential, router, sla

req.rData_internal.tree.push(router.mountpath)

if (req.rData_internal.initDone === true) {
if (req.rData_internal.initDone) {
req.next = next
return next()
}
Expand Down Expand Up @@ -91,9 +91,9 @@ var init = function (options, reqProperties, reqPropertiesEssential, router, sla
Object.defineProperties(req, reqPropertiesEssential) // enabling bare essentials ;)
return next()
}
init.init = true
normInit.init = true

var slaveInit = async (req, res, next) => {
let slaveInit = async (req, res, next) => {
if (route.mountpath) req.rData_internal.tree.push(router.mountpath)
const deh = res.defaultErrHandler
res.defaultErrHandler = defErrHandlerBuilder(deh)
Expand All @@ -102,7 +102,7 @@ var init = function (options, reqProperties, reqPropertiesEssential, router, sla
}
slaveInit.init = true

if (!slave) return init
if (!slave) return normInit
return slaveInit
}

Expand Down
25 changes: 3 additions & 22 deletions lib/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,42 +107,23 @@ function resSend(chunk) { // split to avoid deprecation checks when returning fr
// settings
var app = this.app

var encoding

// write strings in utf-8
if (typeof chunk === 'string') {
encoding = 'utf8'

// reflect this in content-type
if (typeof (type = this.getHeader('Content-Type')) === 'string') {
this.setHeader('Content-Type', setCharset(type, 'utf-8'))
}
}

// populate Content-Length
var len
if (chunk !== undefined) {
if (chunk !== undefined && !req.rData_internal.noEtag && !this.getHeader('ETag')) {

var etag
// determine if ETag should be generated
var etagFn = app.get('etag fn')
var generateETag = etagFn && !req.rData_internal.noEtag && !this.getHeader('ETag')

if (Buffer.isBuffer(chunk)) {
// get length of Buffer
len = chunk.length
} else if (!generateETag && chunk.length < 1000) {
// just calculate length when no ETag + small chunk
len = Buffer.byteLength(chunk, encoding)
} else {
// convert chunk to Buffer and calculate
chunk = Buffer.from(chunk, encoding)
encoding = undefined
len = chunk.length
}

// populate ETag
if (generateETag && (etag = etagFn(chunk, encoding))) { // unlike express, we don't need to check if there is len, because we know it for certain, since we placed this if block in a different place
if (etagFn && (etag = etagFn(chunk))) { // unlike express, we don't need to check if there is len, because we know it for certain, since we placed this if block in a different place
this.setHeader('ETag', etag)
}
}
Expand All @@ -160,7 +141,7 @@ function resSend(chunk) { // split to avoid deprecation checks when returning fr

if (req.rData_internal.method !== 'HEAD') {
// respond
this.end(chunk, encoding)
this.end(chunk)
return this
}
// skip body for HEAD.
Expand Down
1 change: 0 additions & 1 deletion lib/routing/next.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ function next (middlewares, middlewaresArgsNum, req, res, index, routeIndex, rou
return getParams(curRoute)
}
if (curRoute.handlers[curRoute.handlers.length - 1] === middleware) {
// req.routesToProcess.splice(0,1)
routeIndex++
delete req.currentRouteMiddlewareNum
}
Expand Down
11 changes: 3 additions & 8 deletions lib/routing/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var parseUrl = require('parseurl')
var qs = require('qs')

module.exports = function query (req, url, fn) {
const [path, search] = url.split('?')
const path = url.split('?')[0]
req.path = path

if (!req.query) {
Expand All @@ -26,13 +26,8 @@ module.exports = function query (req, url, fn) {
})
}
}
if (!search) {
req.search = '?'
req.query = {}
return
}
req.search = '?' + search
const val = parseUrl(req).query
const val = parseUrl(req).query || ''
req.search = '?' + val
req.query = queryparse(val)
return
}
Expand Down
86 changes: 40 additions & 46 deletions lib/routing/sequential.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ module.exports = (config = {}) => {
return
}
if (req.rData_internal.lastPattern) {
const reqUrlCopy = req.rData_internal.url
req.rData_internal.url = req.rData_internal.url.replace(req.rData_internal.lastPattern, '') || reqUrlCopy
req.rData_internal.url = req.rData_internal.url.replace(req.rData_internal.lastPattern, '')
}
}
init()
Expand All @@ -112,57 +111,52 @@ module.exports = (config = {}) => {
return routeFurther(req, res, step, match)

function routeFurther (req, res, step, match) {
if (match.handlers.length) {
if (!req.rData_internal.specialMode) req.rData_internal.specialMode = match.specialMode || config.specialMode
if (!req.rData_internal.noEtag) req.rData_internal.noEtag = match.noEtag

const middlewares = [...match.handlers]
const middlewaresArgsNum = [...match.handlersArgsNum]

if (step !== undefined) {
// router is being used as a nested router
if (!config.mergeParams) {
req.params = onChange.unsubscribe(req.params)
makeReqParams(req)
}
let fn
if (step && req.stepString && step.toString() !== req.stepString) {
// req.rData_internal.paramsPrev.push(req.params)
fn = function (err) {
req.params = req.rData_internal.paramsPrev[req.rData_internal.paramsPrev.length - 2] || req.rData_internal.paramsPrev[req.rData_internal.paramsPrev.length - 1] || req.params

try {
return step(err)
} catch (e) {
return res.defaultErrHandler(err)
}
}
} else {
fn = (req, res, next) => {
req.rData_internal.url = req.rData_internal.urlPrevious.pop()
req.app = res.app = req.rData_internal.appPrev.pop()
req.rData_internal.tree.pop()

delete req.preRouterUrl
// delete req.preRouterPath
req.next = step
return step()
}
}
middlewares.push(fn)
}

req.rData_internal.specialMode = req.rData_internal.specialMode || match.specialMode || config.specialMode
req.rData_internal.noEtag = req.rData_internal.noEtag || match.noEtag

req.routesToProcess = match.routes
const middlewares = [...match.handlers]
const middlewaresArgsNum = [...match.handlersArgsNum]

if (!req.params) {
if (step) {
// router is being used as a nested router
if (!config.mergeParams) {
req.params = onChange.unsubscribe(req.params)
makeReqParams(req)
}
let fn
if (step && req.stepString && step.toString() !== req.stepString) {

fn = function (err) {
req.params = req.rData_internal.paramsPrev[req.rData_internal.paramsPrev.length - 2] || req.rData_internal.paramsPrev[req.rData_internal.paramsPrev.length - 1] || req.params

return step(err)

}
} else {
fn = (req, res, next) => {
req.rData_internal.url = req.rData_internal.urlPrevious.pop()
req.app = res.app = req.rData_internal.appPrev.pop()
req.rData_internal.tree.pop()

delete req.preRouterUrl

return next(middlewares, middlewaresArgsNum, req, res, 0, 0, routers, config.defaultRoute, config.errorHandler, null)
req.next = step
return step()
}
}
middlewares.push(fn)
}

return config.defaultRoute(req, res) // if we haven't found routes.

req.routesToProcess = match.routes

if (!req.params) {
makeReqParams(req)
}

return next(middlewares, middlewaresArgsNum, req, res, 0, 0, routers, config.defaultRoute, config.errorHandler, null)
}

}

router.on = (method, pattern, ...handlers) => router.add(method, pattern, handlers)
Expand Down
2 changes: 1 addition & 1 deletion lib/routing/trouterFork.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ module.exports = class Trouter {
if (tmp.method.length === 0 || tmp.method === method || (isHEAD && tmp.method === 'GET')) {
const test = tmp.pattern.exec(url)

if (test != null) {
if (test !== null) {
routes.push(tmp)

if (!specialMode) {
Expand Down
3 changes: 3 additions & 0 deletions lib/uwsCompat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = (config) => {
return require('low-http-server')(config)
}
4 changes: 1 addition & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fyrejet",
"version": "2.2.2",
"version": "2.3.0",
"description": "Web Framework for node.js that strives to provide (almost) perfect compatibility with Express, while providing better performance, where you need it.",
"main": "index.js",
"scripts": {
Expand Down Expand Up @@ -82,14 +82,12 @@
"eslint": "2.13.1",
"express-session": "^1.17.1",
"hbs": "^4.1.1",
"istanbul": "0.4.5",
"marked": "^1.2.2",
"method-override": "3.0.0",
"mocha": "^8.2.0",
"morgan": "^1.10.0",
"multiparty": "4.2.2",
"pbkdf2-password": "1.2.1",
"restana": "^4.8.0",
"should": "13.2.3",
"standard": "^14.3.4",
"supertest": "^5.0.0",
Expand Down
28 changes: 28 additions & 0 deletions performance/fyrejet-route-uWS-cluster.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict'

var cluster = require('cluster')

if (cluster.isMaster) {
var numCPUs = require('os').cpus().length
if (!isNaN(parseInt(process.argv[process.argv.length - 1]) ) ) {
numCPUs = parseInt(process.argv[process.argv.length - 1])
}
console.log('using processes: ' + numCPUs)
for (let i = 0; i < numCPUs; i++) {
cluster.fork()
}
} else {
var express = require('../index')

var app = express({
prioRequestsProcessing: false, // without this option set to 'false' uWS is going to be extremely sluggish
server: express.uwsCompat(),
serverType: 'uWebSockets'
})

app.get('/hi', function (req, res) {
res.send('')
})

app.listen(4004)
}
2 changes: 1 addition & 1 deletion performance/fyrejet-route-uWS.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const fyrejet = require('../index')
const uwsCompat = fyrejet.uwsCompat // you will need Rolando Santamaria Maso's (jkyberneees) excellent 0http
const app = require('../index')({
prioRequestsProcessing: false, // without this option set to 'false' uWS is going to be extremely sluggish
server: uwsCompat(),
server: fyrejet.uwsCompat(),
serverType: 'uWebSockets'
})

Expand Down

0 comments on commit f012ff7

Please sign in to comment.