Skip to content

Commit

Permalink
Merge 1ddcd6b into 0b30c5d
Browse files Browse the repository at this point in the history
  • Loading branch information
cdaringe committed Mar 12, 2022
2 parents 0b30c5d + 1ddcd6b commit 46e187e
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 35 deletions.
8 changes: 0 additions & 8 deletions package.json
Expand Up @@ -90,14 +90,6 @@
"is-plain-obj": "^3.0.0",
"micromatch": "^4.0.2"
},
"peerDependencies": {
"@types/express": "^4.17.13"
},
"peerDependenciesMeta": {
"@types/express": {
"optional": true
}
},
"engines": {
"node": ">=12.0.0"
},
Expand Down
5 changes: 2 additions & 3 deletions src/_handlers.ts
@@ -1,5 +1,4 @@
import type * as express from 'express';
import type { Options } from './types';
import type { Request, Response, Options } from './types';
import type * as httpProxy from 'http-proxy';
import { getInstance } from './logger';
const logger = getInstance();
Expand Down Expand Up @@ -53,7 +52,7 @@ export function getHandlers(options: Options) {
return handlers;
}

function defaultErrorHandler(err, req: express.Request, res: express.Response) {
function defaultErrorHandler(err, req: Request, res: Response) {
// Re-throw error. Not recoverable since req & res are empty.
if (!req && !res) {
throw err; // "Error: Must provide a proper URL as target"
Expand Down
4 changes: 2 additions & 2 deletions src/handlers/fix-request-body.ts
Expand Up @@ -5,8 +5,8 @@ import * as querystring from 'querystring';
/**
* Fix proxied body if bodyParser is involved.
*/
export function fixRequestBody(proxyReq: http.ClientRequest, req: http.IncomingMessage): void {
const requestBody = (req as Request).body;
export function fixRequestBody(proxyReq: http.ClientRequest, req: Request): void {
const requestBody = req.body;

if (!requestBody) {
return;
Expand Down
13 changes: 4 additions & 9 deletions src/http-proxy-middleware.ts
@@ -1,6 +1,6 @@
import type * as https from 'https';
import type * as express from 'express';
import type { Request, RequestHandler, Response, Options, Filter } from './types';

import type { Request, Response, Options, Filter, RequestMiddleware } from './types';
import * as httpProxy from 'http-proxy';
import { verifyConfig } from './configuration';
import { matchPathFilter } from './path-filter';
Expand Down Expand Up @@ -35,19 +35,15 @@ export class HttpProxyMiddleware {

// https://github.com/chimurai/http-proxy-middleware/issues/19
// expose function to upgrade externally
(this.middleware as any).upgrade = (req, socket, head) => {
this.middleware.upgrade = (req, socket, head) => {
if (!this.wsInternalSubscribed) {
this.handleUpgrade(req, socket, head);
}
};
}

// https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript#red-flags-for-this
public middleware: RequestHandler = async (
req: Request,
res: Response,
next: express.NextFunction
) => {
public middleware: RequestMiddleware = async (req, res, next) => {
if (this.shouldProxy(this.proxyOptions.pathFilter, req)) {
try {
const activeProxyOptions = await this.prepareProxyRequest(req);
Expand All @@ -58,7 +54,6 @@ export class HttpProxyMiddleware {
} else {
next();
}

/**
* Get the server object to subscribe to server events;
* 'upgrade' for websocket and 'close' for graceful shutdown
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Expand Up @@ -15,4 +15,4 @@ export function createProxyMiddleware(options: Options) {

export * from './handlers';

export { Filter, Options, RequestHandler } from './types';
export { Filter, Options, RequestMiddleware } from './types';
32 changes: 26 additions & 6 deletions src/types.ts
Expand Up @@ -4,20 +4,40 @@
*/

/* eslint-disable @typescript-eslint/no-empty-interface */

import type * as express from 'express';
import type * as http from 'http';
import type * as httpProxy from 'http-proxy';
import type * as net from 'net';
import type * as url from 'url';

export interface Request extends express.Request {}
export interface Response extends express.Response {}
export type Request = http.IncomingMessage;
export type Response = http.ServerResponse;

export interface RequestHandler extends express.RequestHandler {
upgrade?: (req: Request, socket: net.Socket, head: any) => void;
/**
* http-proxy-middleware supports framework specific values. The following
* values are primarily decorated onto IncomingMessage by express, but are
* not required for use.
*/
declare module 'http' {
interface IncomingMessage {
originalUrl?: string;
hostname?: string;
host?: string;
body?: Record<string, any>;
}
}

export type Next = (...args: unknown[]) => unknown;

type RequestMiddlewareFunction = (
req: http.IncomingMessage,
res: http.ServerResponse,
next: Next
) => unknown | Promise<unknown>;

export type RequestMiddleware = RequestMiddlewareFunction & {
upgrade?: (req: Request, socket: net.Socket, head: any) => void;
};

export type Filter = string | string[] | ((pathname: string, req: Request) => boolean);

export interface Options extends httpProxy.ServerOptions {
Expand Down
@@ -1,7 +1,7 @@
import * as express from 'express';
import * as request from 'supertest';
import { createProxyMiddleware } from './test-kit';
import { Options } from '../../src/index';
import { createProxyMiddleware } from '../test-kit';
import { Options } from '../../../src/index';

describe('Usage in Express', () => {
let app: express.Express;
Expand Down
41 changes: 41 additions & 0 deletions test/e2e/servers/http.spec.ts
@@ -0,0 +1,41 @@
import * as http from 'http';
import { createProxyMiddleware } from '../test-kit';
import { Options } from '../../../src/index';
import * as request from 'supertest';
import * as getPort from 'get-port';

describe('http integration', () => {
let server: http.Server | null = null;

afterEach(() => {
server?.close();
});

it('should work with raw node http RequestHandler', async () => {
await new Promise(async (resolve, reject) => {
const port = await getPort();
server = http
.createServer((req, res) => {
const proxyConfig: Options = {
changeOrigin: true,
logLevel: 'silent',
target: 'http://jsonplaceholder.typicode.com',
};
const handler = createProxyMiddleware(proxyConfig);
return handler(req, res, resolve);
})
.listen(port);
request(server)
.get('/')
.expect(200)
.end((err, res) => {
if (err) {
reject(err);
} else {
expect(res.ok).toBe(true);
resolve(res);
}
});
});
});
});
4 changes: 2 additions & 2 deletions test/e2e/websocket.spec.ts
Expand Up @@ -3,7 +3,7 @@ import * as WebSocket from 'ws';
import { Server as WebSocketServer } from 'ws';
import * as getPort from 'get-port';
import { createProxyMiddleware, createApp } from './test-kit';
import type { RequestHandler } from '../../src/types';
import type { RequestMiddleware } from '../../src/types';

/********************************************************************
* - Not possible to use `supertest` to test WebSockets
Expand All @@ -14,7 +14,7 @@ describe('E2E WebSocket proxy', () => {
let proxyServer: http.Server;
let ws: WebSocket;
let wss: WebSocketServer;
let proxyMiddleware: RequestHandler;
let proxyMiddleware: RequestMiddleware;
let WS_SERVER_PORT: number;
let SERVER_PORT: number;

Expand Down
4 changes: 2 additions & 2 deletions test/unit/fix-request-body.spec.ts
Expand Up @@ -44,7 +44,7 @@ describe('fixRequestBody', () => {
jest.spyOn(proxyRequest, 'setHeader');
jest.spyOn(proxyRequest, 'write');

fixRequestBody(proxyRequest, { body: { someField: 'some value' } } as Request);
fixRequestBody(proxyRequest, { body: { someField: 'some value' } } as unknown as Request);

const expectedBody = JSON.stringify({ someField: 'some value' });
expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length);
Expand All @@ -58,7 +58,7 @@ describe('fixRequestBody', () => {
jest.spyOn(proxyRequest, 'setHeader');
jest.spyOn(proxyRequest, 'write');

fixRequestBody(proxyRequest, { body: { someField: 'some value' } } as Request);
fixRequestBody(proxyRequest, { body: { someField: 'some value' } } as unknown as Request);

const expectedBody = querystring.stringify({ someField: 'some value' });
expect(proxyRequest.setHeader).toHaveBeenCalledWith('Content-Length', expectedBody.length);
Expand Down

0 comments on commit 46e187e

Please sign in to comment.