Skip to content

Commit

Permalink
fix(typescript): fix proxyRes and router types (#410)
Browse files Browse the repository at this point in the history
  • Loading branch information
dylang committed Feb 29, 2020
1 parent 47608aa commit 6d30314
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 22 deletions.
12 changes: 10 additions & 2 deletions README.md
Expand Up @@ -228,7 +228,6 @@ Providing an alternative way to decide which requests should be proxied; In case
if (should_add_something) path += "something";
return path;
}

```

- **option.router**: object/function, re-target `option.target` for specific requests.
Expand All @@ -243,11 +242,20 @@ Providing an alternative way to decide which requests should be proxied; In case
'/rest' : 'http://localhost:8004' // path only
}

// Custom router function
// Custom router function (string target)
router: function(req) {
return 'http://localhost:8004';
}

// Custom router function (target object)
router: function(req) {
return {
protocol: 'https:', // The : is required
host: 'localhost',
port: 8004
};
}

// Asynchronous router function which returns promise
router: async function(req) {
const url = await doSomeIO();
Expand Down
8 changes: 4 additions & 4 deletions src/types.ts
Expand Up @@ -18,14 +18,14 @@ export interface Options extends httpProxy.ServerOptions {
| ((path: string, req: Request) => string)
| ((path: string, req: Request) => Promise<string>);
router?:
| { [hostOrPath: string]: string }
| ((req: Request) => string)
| ((req: Request) => Promise<string>);
| { [hostOrPath: string]: httpProxy.ServerOptions['target'] }
| ((req: Request) => httpProxy.ServerOptions['target'])
| ((req: Request) => Promise<httpProxy.ServerOptions['target']>);
logLevel?: 'debug' | 'info' | 'warn' | 'error' | 'silent';
logProvider?(provider: LogProvider): LogProvider;

onError?(err: Error, req: Request, res: Response): void;
onProxyRes?(proxyRes: http.ServerResponse, req: Request, res: Response): void;
onProxyRes?(proxyRes: http.IncomingMessage, req: Request, res: Response): void;
onProxyReq?(proxyReq: http.ClientRequest, req: Request, res: Response): void;
onProxyReqWs?(
proxyReq: http.ClientRequest,
Expand Down
110 changes: 94 additions & 16 deletions test/e2e/router.spec.ts
@@ -1,24 +1,44 @@
import { createProxyMiddleware, createApp, createAppWithPath } from './_utils';
import * as request from 'supertest';
import { getLocal, Mockttp } from 'mockttp';
import { getLocal, generateCACertificate, Mockttp } from 'mockttp';

const untrustedCACert = generateCACertificate({ bits: 1024 });

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

describe('E2E router', () => {
let targetServerA: Mockttp;
let targetServerB: Mockttp;
let targetServerC: Mockttp;

beforeEach(async () => {
targetServerA = getLocal();
targetServerB = getLocal();
targetServerC = getLocal();
targetServerA = getLocal({ https: await untrustedCACert });
targetServerB = getLocal({ https: await untrustedCACert });
targetServerC = getLocal({ https: await untrustedCACert });

await targetServerA
.anyRequest()
.thenPassThrough({ ignoreHostCertificateErrors: ['localhost'] });
await targetServerB
.anyRequest()
.thenPassThrough({ ignoreHostCertificateErrors: ['localhost'] });
await targetServerC
.anyRequest()
.thenPassThrough({ ignoreHostCertificateErrors: ['localhost'] });

await targetServerA
.anyRequest()
.thenCallback(({ protocol }) => ({ body: protocol === 'https' ? 'A' : 'NOT HTTPS A' }));
await targetServerB
.anyRequest()
.thenCallback(({ protocol }) => ({ body: protocol === 'https' ? 'B' : 'NOT HTTPS B' }));
await targetServerC
.anyRequest()
.thenCallback(({ protocol }) => ({ body: protocol === 'https' ? 'C' : 'NOT HTTPS C' }));

await targetServerA.start(6001);
await targetServerB.start(6002);
await targetServerC.start(6003);

targetServerA.get().thenReply(200, 'A');
targetServerB.get().thenReply(200, 'B');
targetServerC.get().thenReply(200, 'C');
});

afterEach(async () => {
Expand All @@ -27,13 +47,50 @@ describe('E2E router', () => {
await targetServerC.stop();
});

describe('router with proxyTable', () => {
it('should proxy to: "localhost:6003/api"', async () => {
describe('router with req', () => {
it('should work with a string', async () => {
const app = createApp(
createProxyMiddleware({
target: 'https://localhost:6001',
secure: false,
changeOrigin: true,
router(req) {
return 'https://localhost:6003';
}
})
);

const agent = request(app);
const response = await agent.get('/api').expect(200);
expect(response.text).toBe('C');
});

it('should work with an object', async () => {
const app = createApp(
createProxyMiddleware({
target: `http://localhost:6001`,
target: 'https://localhost:6001',
secure: false,
changeOrigin: true,
router(req) {
return 'http://localhost:6003';
return { host: 'localhost', port: 6003, protocol: 'https:' };
}
})
);
const agent = request(app);
const response = await agent.get('/api').expect(200);
expect(response.text).toBe('C');
});

it('should work with an async callback', async () => {
const app = createApp(
createProxyMiddleware({
target: 'https://localhost:6001',
secure: false,
changeOrigin: true,
router: async req => {
return new Promise(resolve =>
resolve({ host: 'localhost', port: 6003, protocol: 'https:' })
);
}
})
);
Expand All @@ -42,6 +99,25 @@ describe('E2E router', () => {
const response = await agent.get('/api').expect(200);
expect(response.text).toBe('C');
});

it('missing a : will cause it to use http', async () => {
const app = createApp(
createProxyMiddleware({
target: 'https://localhost:6001',
secure: false,
changeOrigin: true,
router: async req => {
return new Promise(resolve =>
resolve({ host: 'localhost', port: 6003, protocol: 'https' })
);
}
})
);

const agent = request(app);
const response = await agent.get('/api').expect(200);
expect(response.text).toBe('NOT HTTPS C');
});
});

describe('router with proxyTable', () => {
Expand All @@ -51,11 +127,13 @@ describe('E2E router', () => {
const app = createAppWithPath(
'/',
createProxyMiddleware({
target: 'http://localhost:6001',
target: 'https://localhost:6001',
secure: false,
changeOrigin: true,
router: {
'alpha.localhost:6000': 'http://localhost:6001',
'beta.localhost:6000': 'http://localhost:6002',
'localhost:6000/api': 'http://localhost:6003'
'alpha.localhost:6000': 'https://localhost:6001',
'beta.localhost:6000': 'https://localhost:6002',
'localhost:6000/api': 'https://localhost:6003'
}
})
);
Expand Down

0 comments on commit 6d30314

Please sign in to comment.