From e8e961a838b0f037186e583a2b1efd92c7c04511 Mon Sep 17 00:00:00 2001 From: Jason Mulligan Date: Wed, 28 Aug 2024 16:42:22 -0400 Subject: [PATCH] Fixing 'req.exit()' --- README.md | 4 ++-- dist/cli.cjs | 2 +- dist/woodland.cjs | 22 ++++++++++------------ dist/woodland.js | 22 ++++++++++------------ package-lock.json | 4 ++-- package.json | 2 +- src/utility.js | 13 +++++-------- src/woodland.js | 5 +++-- 8 files changed, 34 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 0f3b36f..456ca83 100644 --- a/README.md +++ b/README.md @@ -227,8 +227,8 @@ Executes after the response has been sent. ## Helpers `req` & `res` are decorated with helper functions to simplify responding. -### req.exit(req, res, next) -Exit middleware of the route for the HTTP method as a way to "skip" authentication middleware for unprotected routes. +### req.exit() +Exit the middleware chain if the route is un-protected. ### res.error(status[, body, headers]) Sends an error response. diff --git a/dist/cli.cjs b/dist/cli.cjs index 8576396..a1d432b 100644 --- a/dist/cli.cjs +++ b/dist/cli.cjs @@ -4,7 +4,7 @@ * * @copyright 2024 Jason Mulligan * @license BSD-3-Clause - * @version 20.0.0 + * @version 20.0.1 */ 'use strict'; diff --git a/dist/woodland.cjs b/dist/woodland.cjs index 49f77bc..35191ed 100644 --- a/dist/woodland.cjs +++ b/dist/woodland.cjs @@ -3,7 +3,7 @@ * * @copyright 2024 Jason Mulligan * @license BSD-3-Clause - * @version 20.0.0 + * @version 20.0.1 */ 'use strict'; @@ -192,8 +192,8 @@ function ms (arg = INT_0, digits = INT_3) { return TIME_MS.replace(TOKEN_N, Number(arg / INT_1e6).toFixed(digits)); } -function next (req, res, middleware) { - const fn = err => process.nextTick(() => { +function next (req, res, middleware, immediate = false) { + const internalFn = (err, fn) => { let obj = middleware.next(); if (obj.done === false) { @@ -213,7 +213,8 @@ function next (req, res, middleware) { } else { res.error(getStatus(req, res)); } - }); + }; + const fn = immediate ? () => internalFn(undefined, fn) : err => process.nextTick(() => internalFn(err, fn)); return fn; } @@ -276,7 +277,7 @@ function pipeable (method, arg) { return method !== HEAD && arg !== null && typeof arg.on === FUNCTION; } -function reduce (uri, map = new Map(), arg = {}, end = false) { +function reduce (uri, map = new Map(), arg = {}) { Array.from(map.values()).filter(i => { i.regex.lastIndex = INT_0; @@ -284,10 +285,6 @@ function reduce (uri, map = new Map(), arg = {}, end = false) { }).forEach(i => { for (const fn of i.handlers) { arg.middleware.push(fn); - - if (end && arg.exit === null) { - arg.exit = fn; - } } if (i.params && arg.params === false) { @@ -704,7 +701,7 @@ class Woodland extends node_events.EventEmitter { params(req, result.getParams); } - req.exit = result.exit; + req.exit = next(req, res, result.middleware.slice(result.exit, result.middleware.length)[Symbol.iterator](), true); next(req, res, result.middleware[Symbol.iterator]())(); } else { res.error(getStatus(req, res)); @@ -719,11 +716,12 @@ class Woodland extends node_events.EventEmitter { if (cached !== void 0) { result = cached; } else { - result = {getParams: null, middleware: [], params: false, visible: INT_0, exit: null}; + result = {getParams: null, middleware: [], params: false, visible: INT_0, exit: -1}; reduce(uri, this.middleware.get(WILDCARD), result); if (method !== WILDCARD) { - reduce(uri, this.middleware.get(method), result, true); + result.exit = result.middleware.length; + reduce(uri, this.middleware.get(method), result); } result.visible = result.middleware.filter(i => this.ignored.has(i) === false).length; diff --git a/dist/woodland.js b/dist/woodland.js index 0cc2a5e..6aa107a 100644 --- a/dist/woodland.js +++ b/dist/woodland.js @@ -3,7 +3,7 @@ * * @copyright 2024 Jason Mulligan * @license BSD-3-Clause - * @version 20.0.0 + * @version 20.0.1 */ import {STATUS_CODES,METHODS}from'node:http';import {join,extname}from'node:path';import {EventEmitter}from'node:events';import {stat,readdir}from'node:fs/promises';import {etag}from'tiny-etag';import {precise}from'precise';import {lru}from'tiny-lru';import {createRequire}from'node:module';import {fileURLToPath,URL}from'node:url';import {readFileSync,createReadStream}from'node:fs';import {coerce}from'tiny-coerce';import mimeDb from'mime-db';const __dirname$1 = fileURLToPath(new URL(".", import.meta.url)); const require = createRequire(import.meta.url); @@ -174,8 +174,8 @@ function ms (arg = INT_0, digits = INT_3) { return TIME_MS.replace(TOKEN_N, Number(arg / INT_1e6).toFixed(digits)); } -function next (req, res, middleware) { - const fn = err => process.nextTick(() => { +function next (req, res, middleware, immediate = false) { + const internalFn = (err, fn) => { let obj = middleware.next(); if (obj.done === false) { @@ -195,7 +195,8 @@ function next (req, res, middleware) { } else { res.error(getStatus(req, res)); } - }); + }; + const fn = immediate ? () => internalFn(undefined, fn) : err => process.nextTick(() => internalFn(err, fn)); return fn; } @@ -258,7 +259,7 @@ function pipeable (method, arg) { return method !== HEAD && arg !== null && typeof arg.on === FUNCTION; } -function reduce (uri, map = new Map(), arg = {}, end = false) { +function reduce (uri, map = new Map(), arg = {}) { Array.from(map.values()).filter(i => { i.regex.lastIndex = INT_0; @@ -266,10 +267,6 @@ function reduce (uri, map = new Map(), arg = {}, end = false) { }).forEach(i => { for (const fn of i.handlers) { arg.middleware.push(fn); - - if (end && arg.exit === null) { - arg.exit = fn; - } } if (i.params && arg.params === false) { @@ -684,7 +681,7 @@ function writeHead (res, headers = {}) { params(req, result.getParams); } - req.exit = result.exit; + req.exit = next(req, res, result.middleware.slice(result.exit, result.middleware.length)[Symbol.iterator](), true); next(req, res, result.middleware[Symbol.iterator]())(); } else { res.error(getStatus(req, res)); @@ -699,11 +696,12 @@ function writeHead (res, headers = {}) { if (cached !== void 0) { result = cached; } else { - result = {getParams: null, middleware: [], params: false, visible: INT_0, exit: null}; + result = {getParams: null, middleware: [], params: false, visible: INT_0, exit: -1}; reduce(uri, this.middleware.get(WILDCARD), result); if (method !== WILDCARD) { - reduce(uri, this.middleware.get(method), result, true); + result.exit = result.middleware.length; + reduce(uri, this.middleware.get(method), result); } result.visible = result.middleware.filter(i => this.ignored.has(i) === false).length; diff --git a/package-lock.json b/package-lock.json index 983bf8c..6a524ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "woodland", - "version": "20.0.0", + "version": "20.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "woodland", - "version": "20.0.0", + "version": "20.0.1", "license": "BSD-3-Clause", "dependencies": { "mime-db": "^1.53.0", diff --git a/package.json b/package.json index e614039..23c5dae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "woodland", - "version": "20.0.0", + "version": "20.0.1", "description": "Lightweight HTTP framework with automatic headers", "type": "module", "types": "types/woodland.d.ts", diff --git a/src/utility.js b/src/utility.js index 9366475..217c2b8 100644 --- a/src/utility.js +++ b/src/utility.js @@ -79,8 +79,8 @@ export function ms (arg = INT_0, digits = INT_3) { return TIME_MS.replace(TOKEN_N, Number(arg / INT_1e6).toFixed(digits)); } -export function next (req, res, middleware) { - const fn = err => process.nextTick(() => { +export function next (req, res, middleware, immediate = false) { + const internalFn = (err, fn) => { let obj = middleware.next(); if (obj.done === false) { @@ -100,7 +100,8 @@ export function next (req, res, middleware) { } else { res.error(getStatus(req, res)); } - }); + }; + const fn = immediate ? () => internalFn(undefined, fn) : err => process.nextTick(() => internalFn(err, fn)); return fn; } @@ -163,7 +164,7 @@ export function pipeable (method, arg) { return method !== HEAD && arg !== null && typeof arg.on === FUNCTION; } -export function reduce (uri, map = new Map(), arg = {}, end = false) { +export function reduce (uri, map = new Map(), arg = {}) { Array.from(map.values()).filter(i => { i.regex.lastIndex = INT_0; @@ -171,10 +172,6 @@ export function reduce (uri, map = new Map(), arg = {}, end = false) { }).forEach(i => { for (const fn of i.handlers) { arg.middleware.push(fn); - - if (end && arg.exit === null) { - arg.exit = fn; - } } if (i.params && arg.params === false) { diff --git a/src/woodland.js b/src/woodland.js index 47b4942..4c36f9c 100644 --- a/src/woodland.js +++ b/src/woodland.js @@ -465,7 +465,7 @@ export class Woodland extends EventEmitter { params(req, result.getParams); } - req.exit = result.exit; + req.exit = next(req, res, result.middleware.slice(result.exit, result.middleware.length)[Symbol.iterator](), true); next(req, res, result.middleware[Symbol.iterator]())(); } else { res.error(getStatus(req, res)); @@ -480,10 +480,11 @@ export class Woodland extends EventEmitter { if (cached !== void 0) { result = cached; } else { - result = {getParams: null, middleware: [], params: false, visible: INT_0, exit: null}; + result = {getParams: null, middleware: [], params: false, visible: INT_0, exit: -1}; reduce(uri, this.middleware.get(WILDCARD), result); if (method !== WILDCARD) { + result.exit = result.middleware.length; reduce(uri, this.middleware.get(method), result, true); }