Skip to content

Commit

Permalink
feat: add socketConnectionTimeout
Browse files Browse the repository at this point in the history
  • Loading branch information
gajus committed Sep 13, 2019
1 parent 02ee6fb commit fa6d1b8
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 9 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,12 @@ Use [`roarr-cli`](https://github.com/gajus/roarr-cli) program to pretty-print th
/**
* @property environmentVariableNamespace Defines namespace of `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` environment variables. (Default: `GLOBAL_AGENT_`)
* @property forceGlobalAgent Forces to use `global-agent` HTTP(S) agent even when request was explicitly constructed with another agent. (Default: `true`)
* @property socketConnectionTimeout Destroys socket if connection is not established within the timeout. (Default: `5000`)
*/
type ProxyAgentConfigurationInputType = {|
+environmentVariableNamespace?: string,
+forceGlobalAgent?: boolean
+forceGlobalAgent?: boolean,
+socketConnectionTimeout?: number,
|};

(configurationInput: ProxyAgentConfigurationInputType) => ProxyAgentConfigurationType;
Expand All @@ -182,6 +184,7 @@ type ProxyAgentConfigurationInputType = {|
|---|---|---|
|`GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE`|Defines namespace of `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` environment variables.|`GLOBAL_AGENT_`|
|`GLOBAL_AGENT_FORCE_GLOBAL_AGENT`|Forces to use `global-agent` HTTP(S) agent even when request was explicitly constructed with another agent.|`true`|
|`GLOBAL_AGENT_SOCKET_CONNECTION_TIMEOUT`|Destroys socket if connection is not established within the timeout.|`5000`|
|`${NAMESPACE}_HTTP_PROXY`|Sets the initial proxy controller HTTP_PROXY value.|N/A|
|`${NAMESPACE}_HTTPS_PROXY`|Sets the initial proxy controller HTTPS_PROXY value.|N/A|
|`${NAMESPACE}_NO_PROXY`|Sets the initial proxy controller NO_PROXY value.|N/A|
Expand Down
17 changes: 16 additions & 1 deletion src/classes/Agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,20 @@ class Agent {

getUrlProxy: GetUrlProxyMethodType;

socketConnectionTimeout: number;

constructor (
isProxyConfigured: IsProxyConfiguredMethodType,
mustUrlUseProxy: MustUrlUseProxyMethodType,
getUrlProxy: GetUrlProxyMethodType,
fallbackAgent: AgentType
fallbackAgent: AgentType,
socketConnectionTimeout: number
) {
this.fallbackAgent = fallbackAgent;
this.isProxyConfigured = isProxyConfigured;
this.mustUrlUseProxy = mustUrlUseProxy;
this.getUrlProxy = getUrlProxy;
this.socketConnectionTimeout = socketConnectionTimeout;
}

addRequest (request: *, configuration: *) {
Expand Down Expand Up @@ -118,9 +122,20 @@ class Agent {

// $FlowFixMe It appears that Flow is missing the method description.
this.createConnection(connectionConfiguration, (error, socket) => {
// @see https://github.com/nodejs/node/issues/5757#issuecomment-305969057
socket.setTimeout(this.socketConnectionTimeout, () => {
socket.destroy();
});

socket.once('connect', () => {
socket.setTimeout(0);
});

if (error) {
request.emit('error', error);
} else {
log.debug('created socket');

socket.on('error', (socketError) => {
log.error({
error: serializeError(socketError),
Expand Down
18 changes: 11 additions & 7 deletions src/factories/createGlobalProxyAgent.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const log = Logger.child({
const defaultConfigurationInput = {
environmentVariableNamespace: undefined,
forceGlobalAgent: undefined,
socketConnectionTimeout: 5000,
};

const omitUndefined = (subject) => {
Expand All @@ -54,12 +55,13 @@ const omitUndefined = (subject) => {
};

const createConfiguration = (configurationInput: ProxyAgentConfigurationInputType): ProxyAgentConfigurationType => {
const defaultConfiguration = {
// eslint-disable-next-line no-process-env
environmentVariableNamespace: typeof process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE === 'string' ? process.env.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE : 'GLOBAL_AGENT_',
// eslint-disable-next-line no-process-env
const environment = process.env;

// eslint-disable-next-line no-process-env
forceGlobalAgent: typeof process.env.GLOBAL_AGENT_FORCE_GLOBAL_AGENT === 'string' ? parseBoolean(process.env.GLOBAL_AGENT_FORCE_GLOBAL_AGENT) : true,
const defaultConfiguration = {
environmentVariableNamespace: typeof environment.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE === 'string' ? environment.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE : 'GLOBAL_AGENT_',
forceGlobalAgent: typeof environment.GLOBAL_AGENT_FORCE_GLOBAL_AGENT === 'string' ? parseBoolean(environment.GLOBAL_AGENT_FORCE_GLOBAL_AGENT) : true,
socketConnectionTimeout: typeof environment.GLOBAL_AGENT_SOCKET_CONNECTION_TIMEOUT === 'string' ? parseInt(environment.GLOBAL_AGENT_SOCKET_CONNECTION_TIMEOUT, 10) : defaultConfigurationInput.socketConnectionTimeout,
};

return {
Expand Down Expand Up @@ -125,7 +127,8 @@ export default (configurationInput: ProxyAgentConfigurationInputType = defaultCo
},
mustUrlUseProxy(getHttpProxy),
getUrlProxy(getHttpProxy),
http.globalAgent
http.globalAgent,
configuration.socketConnectionTimeout
);
}
};
Expand All @@ -144,7 +147,8 @@ export default (configurationInput: ProxyAgentConfigurationInputType = defaultCo
},
mustUrlUseProxy(getHttpsProxy),
getUrlProxy(getHttpsProxy),
https.globalAgent
https.globalAgent,
configuration.socketConnectionTimeout
);
}
};
Expand Down
2 changes: 2 additions & 0 deletions src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ export type ProtocolType = 'http:' | 'https:';
export type ProxyAgentConfigurationInputType = {|
+environmentVariableNamespace?: string,
+forceGlobalAgent?: boolean,
+socketConnectionTimeout?: number,
|};

export type ProxyAgentConfigurationType = {|
+environmentVariableNamespace: string,
+forceGlobalAgent: boolean,
+socketConnectionTimeout: number,
|};

0 comments on commit fa6d1b8

Please sign in to comment.