Skip to content

Commit 8adbb4a

Browse files
committed
Fixed conflict in the PR#3 by thibauts
1 parent 6bbbef7 commit 8adbb4a

3 files changed

Lines changed: 39 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ The `opts` argument may either be a string URI of the proxy server to use, or an
104104
* `host` - String - Proxy host to connect to (may use `hostname` as well). Required.
105105
* `port` - Number - Proxy port to connect to. Required.
106106
* `secureProxy` - Boolean - If `true`, then use TLS to connect to the proxy. Defaults to `false`.
107+
* `timeout` - Number - Proxy response timeout in milliseconds.
107108
* `headers` - Object - Additional HTTP headers to be sent on the HTTP CONNECT method.
108109
* Any other options given are passed to the `net.connect()`/`tls.connect()` functions.
109110

https-proxy-agent.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ function HttpsProxyAgent (opts) {
4040
proxy.host = proxy.hostname || proxy.host;
4141
proxy.port = +proxy.port || (this.secureProxy ? 443 : 80);
4242

43+
if(opts.timeout) {
44+
this.timeout = opts.timeout;
45+
}
46+
4347
if (proxy.host && proxy.path) {
4448
// if both a `host` and `path` are specified then it's most likely the
4549
// result of a `url.parse()` call... we need to remove the `path` portion so
@@ -70,6 +74,10 @@ function connect (req, opts, fn) {
7074
socket = net.connect(proxy);
7175
}
7276

77+
if(this.timeout) {
78+
socket.setTimeout(this.timeout);
79+
}
80+
7381
// we need to buffer any HTTP traffic that happens with the proxy before we get
7482
// the CONNECT response, so that if the response is anything other than an "200"
7583
// response code, then we can re-play the "data" events on the socket once the
@@ -89,12 +97,22 @@ function connect (req, opts, fn) {
8997
socket.removeListener('error', onerror);
9098
socket.removeListener('close', onclose);
9199
socket.removeListener('readable', read);
100+
socket.removeListener('timeout', ontimeout);
92101
}
93102

94103
function onclose (err) {
95104
debug('onclose had error %o', err);
96105
}
97106

107+
function ontimeout () {
108+
var err = new Error('Proxy connection timed out');
109+
err.code = 'ETIMEOUT';
110+
cleanup();
111+
// prevent unhandled `error` events
112+
socket.destroy();
113+
fn(err);
114+
}
115+
98116
function onend () {
99117
debug('onend');
100118
}
@@ -182,6 +200,7 @@ function connect (req, opts, fn) {
182200
socket.on('error', onerror);
183201
socket.on('close', onclose);
184202
socket.on('end', onend);
203+
socket.on('timeout', ontimeout);
185204

186205
if (socket.read) {
187206
read();

test/test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,26 @@ describe('HttpsProxyAgent', function () {
223223
done();
224224
});
225225
});
226+
it('should emit an "error" event on the `http.ClientRequest` if the proxy times out', function(done) {
227+
// ensure we timeout after the "error" event had a chance to trigger
228+
this.timeout(1000);
229+
230+
var agent = new HttpsProxyAgent({
231+
host: '255.0.0.1', // unsassigned address, should timeout
232+
port: 8080,
233+
timeout: 500
234+
});
226235

236+
var opts = url.parse('http://nodejs.org');
237+
opts.agent = agent;
238+
239+
var req = http.get(opts);
240+
req.once('error', function(err) {
241+
assert.equal('ETIMEOUT', err.code);
242+
req.abort();
243+
done();
244+
});
245+
});
227246
it('should allow custom proxy "headers"', function (done) {
228247
server.once('connect', function (req, socket, head) {
229248
assert.equal('CONNECT', req.method);

0 commit comments

Comments
 (0)