Skip to content

Commit

Permalink
feat: support variable request_timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
AnWeber committed Jul 30, 2024
1 parent bdd6338 commit e5ea3a5
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 9 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
## [unreleased]
### Features
- add support to define timeout per request using `request.timeout` or setting variable `request_timeout`

### Fix
- variables in gql Query body are replaced (AnWeber/vscode-httpyac#303)
- allow defaultHeaders to overwrite accept or user-agent header
Expand Down
1 change: 1 addition & 0 deletions src/models/httpRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface Request<TMethod extends string = string, TBody = RequestBody> {
noRejectUnauthorized?: boolean;
noRedirect?: boolean;
proxy?: string;
timeout?: number;
}

export interface HttpRequest extends Request<HttpMethod> {
Expand Down
28 changes: 23 additions & 5 deletions src/plugins/core/request/setEnvRequestOptions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,59 @@ import { setEnvRequestOptions } from './setEnvRequestOptions';
describe('setEnvRequestOptions', () => {
describe('setEnvRequestOptions', () => {
it('should set rejectUnauthorized=false', async () => {
const request: models.Request = { protocol: 'HTTP' };
const request: models.Request = { protocol: 'HTTP', url: 'url' };
await setEnvRequestOptions(request, {
variables: { request_rejectUnauthorized: false },
} as unknown as models.ProcessorContext);
expect(request.noRejectUnauthorized).toEqual(true);
});
it('should set rejectUnauthorized=false', async () => {
const request: models.Request = { protocol: 'HTTP' };
const request: models.Request = { protocol: 'HTTP', url: 'url' };
await setEnvRequestOptions(request, {
variables: { request_rejectUnauthorized: 'false' },
} as unknown as models.ProcessorContext);
expect(request.noRejectUnauthorized).toEqual(true);
});
it('should set rejectUnauthorized=true', async () => {
const request: models.Request = { protocol: 'HTTP' };
const request: models.Request = { protocol: 'HTTP', url: 'url' };
await setEnvRequestOptions(request, {
variables: { request_rejectUnauthorized: 'true' },
} as unknown as models.ProcessorContext);
expect(request.noRejectUnauthorized).toEqual(false);
});
it('should ignore rejectUnauthorized', async () => {
const request: models.Request = { protocol: 'HTTP' };
const request: models.Request = { protocol: 'HTTP', url: 'url' };
await setEnvRequestOptions(request, {
variables: {},
} as unknown as models.ProcessorContext);
expect(request.noRejectUnauthorized).toBeUndefined();
});
it('should set proxy', async () => {
const request: models.Request = { protocol: 'HTTP' };
const request: models.Request = { protocol: 'HTTP', url: 'url' };
await setEnvRequestOptions(request, {
variables: {
request_proxy: 'http://localhost:8080',
},
} as unknown as models.ProcessorContext);
expect(request.proxy).toBe('http://localhost:8080');
});
it('should set proxy', async () => {
const request: models.Request = { protocol: 'HTTP', url: 'url' };
await setEnvRequestOptions(request, {
variables: {
request_proxy: 'http://localhost:8080',
},
} as unknown as models.ProcessorContext);
expect(request.proxy).toBe('http://localhost:8080');
});
it('should set timeout', async () => {
const request: models.Request = { protocol: 'HTTP', url: 'url' };
await setEnvRequestOptions(request, {
variables: {
request_timeout: '500',
},
} as unknown as models.ProcessorContext);
expect(request.timeout).toBe(500);
});
});
});
8 changes: 8 additions & 0 deletions src/plugins/core/request/setEnvRequestOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export async function setEnvRequestOptions(
await setEnvRejectUnauthorized(request, variables);
await setEnvNoRedirect(request, variables);
await setEnvProxy(request, variables);
await setEnvRequestTimeout(request, variables);
}

async function setEnvRejectUnauthorized(request: models.Request, variables: models.Variables): Promise<void> {
Expand All @@ -31,3 +32,10 @@ async function setEnvProxy(request: models.Request, variables: models.Variables)
request.proxy = variables.request_proxy;
}
}

async function setEnvRequestTimeout(request: models.Request, variables: models.Variables): Promise<void> {
const timeout = utils.toNumber(variables?.request_timeout);
if (timeout !== undefined) {
request.timeout = timeout;
}
}
2 changes: 1 addition & 1 deletion src/plugins/grpc/callOptionsRequestHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export async function callOptionsRequestHook(request: models.Request, context: m
if (isGrpcRequest(request) && request.headers) {
utils.report(context, 'create call options');
if (context.config?.request?.timeout) {
const timeout = utils.toNumber(context.config?.request?.timeout) || 0;
const timeout = request.timeout || utils.toNumber(context.config?.request?.timeout) || 0;
request.callOptions = Object.assign({}, request.options, {

This comment has been minimized.

Copy link
@d3m3vilurr

d3m3vilurr Jul 31, 2024

imo, a logic should be

if (request.timeout || context.config?.reqeust?.timeout) {
  const timeout = ...
}

in my case, context.config?.reqeust?.timeout is undefined, timeout wouldn't be changed in this case

This comment has been minimized.

Copy link
@AnWeber

AnWeber Jul 31, 2024

Author Owner

I will test it, but if request.timeout is set this variable is used. request.options.timeout is a special feature of http requests and is not supported by grpc. Because of that the explicit logic with request.timeout. I deliberately make the API very open, even if this is not always ideal. And in this case, request.options is a special feature for http only

This comment has been minimized.

Copy link
@AnWeber

AnWeber Aug 3, 2024

Author Owner

@d3m3vilurr now I see the mistake. thanks:-)

deadline: new Date(new Date().getTime() + timeout),
});
Expand Down
1 change: 1 addition & 0 deletions src/plugins/http/gotUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export function getClientOptions(
method: request.method,
headers: request.headers,
body: request.body,
timeout: request.timeout,
},
request.options
);
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/mqtt/mqttRequestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,9 @@ export class MQTTRequestClient extends models.AbstractRequestClient<MqttClient |

const configOptions: IClientOptions = {};
if (config?.request) {
if (config.request.timeout !== undefined) {
configOptions.connectTimeout = utils.toNumber(config.request.timeout);
const timeout = request.timeout || utils.toNumber(config.request.timeout);
if (timeout !== undefined) {
configOptions.connectTimeout = timeout;
}
if (!utils.isUndefined(config.request.rejectUnauthorized)) {
configOptions.rejectUnauthorized = utils.toBoolean(config.request.rejectUnauthorized, true);
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/websocket/websocketRequestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ export class WebsocketRequestClient extends models.AbstractRequestClient<WebSock

const configOptions: ClientOptions = {};
if (config?.request) {
configOptions.handshakeTimeout = utils.toNumber(config.request.timeout);
configOptions.handshakeTimeout = request.timeout || utils.toNumber(config.request.timeout);
configOptions.sessionTimeout = configOptions.handshakeTimeout;
if (!utils.isUndefined(config.request.rejectUnauthorized)) {
configOptions.rejectUnauthorized = utils.toBoolean(config.request.rejectUnauthorized, true);
}
Expand Down

0 comments on commit e5ea3a5

Please sign in to comment.