Skip to content

Commit

Permalink
feat(http-forwarder): add support for timeout and cancelToken (#309)
Browse files Browse the repository at this point in the history
  • Loading branch information
P0lip committed May 19, 2019
1 parent 4b6458a commit 8e1db46
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
11 changes: 9 additions & 2 deletions packages/http/src/forwarder/HttpForwarder.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { IForwarder, IPrismInput } from '@stoplight/prism-core';
import { IHttpOperation, IServer } from '@stoplight/types';
import axios from 'axios';
import axios, { CancelToken } from 'axios';
import { URL } from 'url';
import { IHttpConfig, IHttpNameValue, IHttpRequest, IHttpResponse } from '../types';

export class HttpForwarder implements IForwarder<IHttpOperation, IHttpRequest, IHttpConfig, IHttpResponse> {
public async forward(opts: { resource?: IHttpOperation; input: IPrismInput<IHttpRequest> }): Promise<IHttpResponse> {
public async forward(opts: {
resource?: IHttpOperation;
input: IPrismInput<IHttpRequest>;
timeout?: number;
cancelToken?: CancelToken;
}): Promise<IHttpResponse> {
const inputData = opts.input.data;
const baseUrl =
opts.resource && opts.resource.servers && opts.resource.servers.length > 0
Expand All @@ -25,6 +30,8 @@ export class HttpForwarder implements IForwarder<IHttpOperation, IHttpRequest, I
data: inputData.body,
headers: this.updateHostHeaders(baseUrl, inputData.headers),
validateStatus: () => true,
timeout: Math.max(opts.timeout || 0, 0),
...(opts.cancelToken !== undefined && { cancelToken: opts.cancelToken }),
});

return {
Expand Down
53 changes: 53 additions & 0 deletions packages/http/src/forwarder/__tests__/HttpForwarder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ describe('HttpForwarder', () => {
baseURL: 'http://api.example.com',
responseType: 'text',
validateStatus: expect.any(Function),
timeout: 0,
});
});
});
Expand Down Expand Up @@ -65,6 +66,7 @@ describe('HttpForwarder', () => {
responseType: 'text',
validateStatus: expect.any(Function),
headers: { 'x-test': 'b' },
timeout: 0,
});
});
});
Expand Down Expand Up @@ -92,6 +94,7 @@ describe('HttpForwarder', () => {
host: 'api.example.com',
forwarded: 'host=localhost',
},
timeout: 0,
});
});
});
Expand Down Expand Up @@ -125,6 +128,7 @@ describe('HttpForwarder', () => {
baseURL: 'http://api.example.com',
responseType: 'text',
validateStatus: expect.any(Function),
timeout: 0,
});
});
});
Expand Down Expand Up @@ -193,5 +197,54 @@ describe('HttpForwarder', () => {
});
});
});

describe('timeout is provided', () => {
it('overrides default timeout', async () => {
await forwarder.forward({
input: {
...httpRequests[0],
data: {
...httpInputs[0],
url: { ...httpInputs[0].url, baseUrl: 'http://api.example.com' },
},
},
timeout: 100,
});

expect(axios.default).toHaveBeenCalledWith(expect.objectContaining({ timeout: 100 }));
});

it('cannot be lower than 0', async () => {
await forwarder.forward({
input: {
...httpRequests[0],
data: {
...httpInputs[0],
url: { ...httpInputs[0].url, baseUrl: 'http://api.example.com' },
},
},
timeout: -2,
});

expect(axios.default).toHaveBeenCalledWith(expect.objectContaining({ timeout: 0 }));
});
});

it('accepts cancel token', async () => {
const cancelToken = { token: 'foo' } as any;
await forwarder.forward({
input: {
...httpRequests[0],
data: {
...httpInputs[0],
url: { ...httpInputs[0].url, baseUrl: 'http://api.example.com' },
},
},
timeout: 100,
cancelToken,
});

expect(axios.default).toHaveBeenCalledWith(expect.objectContaining({ cancelToken }));
});
});
});
2 changes: 2 additions & 0 deletions packages/http/src/forwarder/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import axios from 'axios';
import { HttpForwarder } from './HttpForwarder';

const forwarder = new HttpForwarder();

export { forwarder };
export const CancelToken = axios.CancelToken;

0 comments on commit 8e1db46

Please sign in to comment.