From 08c8b9ba37f532a6189588c557b525cc84836f31 Mon Sep 17 00:00:00 2001 From: Vladyslav Tkachenko Date: Sat, 12 Aug 2023 15:50:44 +0300 Subject: [PATCH] feat: add context --- README.md | 24 +++++++++++++++++++----- src/Prxi.ts | 22 ++++++++++++++-------- src/interfaces/RequestHandler.ts | 11 +++++++---- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 6b3f12d..c3e6fa7 100644 --- a/README.md +++ b/README.md @@ -100,12 +100,19 @@ const requestHandlers = [ { // function to test the incoming request // if returns true `handle` function will process the request - isMatching: (method: HttpMethod, path: string): boolean => true, + isMatching: (method: HttpMethod, path: string, context: Record): boolean => true, /** * Request handler */ - handle: async (req: IncomingMesssage, res: ServerResponse, proxyRequest: ProxyRequest): Promise => { + handle: async ( + req: IncomingMesssage, + res: ServerResponse, + proxyRequest: ProxyRequest, + method: HttpMethod, + path: string, + context: Record + ): Promise => { // proxy incoming request to the upstream // optionally pass ProxyRequestConfiguration object as a parameter await proxyRequest({ @@ -142,15 +149,22 @@ const webSocketHandlers = [ { // function to test the incoming request // if returns true `handle` function will process the request - isMatching: (path: string): boolean => true, + isMatching: (path: string, context: Record): boolean => true, /** * Request handler */ - handle: async (req: IncomingMessage, socket: Duplex, head: Buffer, handle: () => Promise): Promise => { + handle: async ( + req: IncomingMessage, + socket: Socket, + head: Buffer, + proxyRequest: ProxyRequest, + path: string, + context: Record + ): Promise => { // proxy incoming request to the upstream // optionally pass ProxyRequestConfiguration object as a parameter - await handle( + await proxyRequest( // optionally provide alternative path for the upstream request url: '/another/path', diff --git a/src/Prxi.ts b/src/Prxi.ts index a62022e..b0cc0a1 100644 --- a/src/Prxi.ts +++ b/src/Prxi.ts @@ -74,7 +74,7 @@ export class Prxi { this.logInfo(`[${requestId}] [Prxi] Handling incoming request for method: ${req.method} and path: ${path}`); - const {handler, upstream, proxy} = Prxi.findRequestHandler(proxies, upstreamConfigurations, req.method, path); + const {handler, upstream, proxy, context} = Prxi.findRequestHandler(proxies, upstreamConfigurations, req.method, path); if (handler) { /* istanbul ignore next */ if (upstream.errorHandler) { @@ -89,7 +89,6 @@ export class Prxi { ); RequestUtils.updateResponseHeaders(res, headersToSet); - handler.handle( req, res, @@ -98,7 +97,7 @@ export class Prxi { ): Promise => { this.logInfo(`[${requestId}] [Prxi] Handling HTTP proxy request for path: ${path}`); await proxy.http.proxy(requestId, req, res, proxyConfiguration); - }, path).catch((err) => { + }, req.method, path, context).catch((err) => { this.logError(`[${requestId}] [Prxi] Error occurred upon making the "${req.method}:${path}" request`, err); errorHandler(req, res, err).catch(err => { this.logError(`[${requestId}] [Prxi] Unable to handle error with errorHandler`, err); @@ -121,7 +120,7 @@ export class Prxi { const requestId = id++; const path = RequestUtils.getPath(req); - const {handler, proxy} = Prxi.findWebSocketHandler(proxies, upstreamConfigurations, path); + const {handler, proxy, context} = Prxi.findWebSocketHandler(proxies, upstreamConfigurations, path); this.logInfo(`[${requestId}] [Prxi] Upgrade event received on path: ${path}`); // handle websocket @@ -133,7 +132,7 @@ export class Prxi { handler.handle(req, socket, head, async (proxyConfiguration?: ProxyRequestConfiguration): Promise => { this.logInfo(`[${requestId}] [Prxi] Handling WS proxy request for path: ${path}`); await proxy.ws.proxy(requestId, req, socket, head, proxyConfiguration); - }, path) + }, path, context) .catch(err => { this.logError(`[${requestId}] [Prxi] Unable to handle websocket request`, err); @@ -182,15 +181,18 @@ export class Prxi { proxy: Proxy | null, handler: RequestHandlerConfig | null, upstream: UpstreamConfiguration | null, + context: Record } | null { + const context = {}; for (const upstream of configs) { - const handler = upstream.requestHandlers?.find(i => i.isMatching(method, path)); + const handler = upstream.requestHandlers?.find(i => i.isMatching(method, path, context)); if (handler) { const proxy = proxies.find(p => p.upstream === upstream); return { proxy, handler, upstream, + context }; } } @@ -199,6 +201,7 @@ export class Prxi { proxy: null, handler: null, upstream: null, + context, }; } @@ -212,15 +215,18 @@ export class Prxi { proxy: Proxy | null, handler: WebSocketHandlerConfig | null, upstream: UpstreamConfiguration | null, + context: Record } | null { + const context = {}; for (const upstream of configs) { - const handler = upstream.webSocketHandlers?.find(i => i.isMatching(path)); + const handler = upstream.webSocketHandlers?.find(i => i.isMatching(path, context)); if (handler) { const proxy = proxies.find(p => p.upstream === upstream); return { proxy, handler, upstream, + context, }; } } @@ -229,8 +235,8 @@ export class Prxi { proxy: null, handler: null, upstream: null, + context, }; - } /** diff --git a/src/interfaces/RequestHandler.ts b/src/interfaces/RequestHandler.ts index 1bdf7fa..2216e11 100644 --- a/src/interfaces/RequestHandler.ts +++ b/src/interfaces/RequestHandler.ts @@ -3,14 +3,16 @@ import { Socket } from 'net'; import { ProxyRequestConfiguration } from './ProxyRequestConfiguration'; export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD'; -export type IsMatchingRequestFunction = (method: HttpMethod, path: string) => boolean; -export type IsMatchingWebSocketFunction = (path: string) => boolean; +export type IsMatchingRequestFunction = (method: HttpMethod, path: string, context: Record) => boolean; +export type IsMatchingWebSocketFunction = (path: string, context: Record) => boolean; export type ProxyRequest = (configuration?: ProxyRequestConfiguration) => Promise; export type HandleFunction = ( req: IncomingMessage, res: ServerResponse, proxyRequest: ProxyRequest, - path: string + method: HttpMethod, + path: string, + context: Record ) => Promise; export type WebSocketHandlerFunction = ( @@ -18,7 +20,8 @@ export type WebSocketHandlerFunction = ( socket: Socket, head: Buffer, proxyRequest: ProxyRequest, - path: string + path: string, + context: Record ) => Promise; export interface WebSocketHandlerConfig {