diff --git a/README.md b/README.md index 5b2d0b3a2..6299ac4f5 100644 --- a/README.md +++ b/README.md @@ -374,6 +374,7 @@ proxyServer.listen(8015); ``` * **headers**: object with extra headers to be added to target requests. * **proxyTimeout**: timeout (in millis) for outgoing proxy requests +* **proxyTimeoutCustomError**: true/false, default: false - specify whether you want to throw a custom `ETIMEDOUT` error when the `proxyTimeout` is reached. If false then the default `ECONNRESET` error will be thrown. * **timeout**: timeout (in millis) for incoming requests * **followRedirects**: true/false, Default: false - specify whether you want to follow redirects * **selfHandleResponse** true/false, if set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the `proxyRes` event diff --git a/lib/http-proxy/passes/web-incoming.js b/lib/http-proxy/passes/web-incoming.js index 7ae735514..3784d12c1 100644 --- a/lib/http-proxy/passes/web-incoming.js +++ b/lib/http-proxy/passes/web-incoming.js @@ -138,7 +138,12 @@ module.exports = { // show an error page at the initial request if(options.proxyTimeout) { proxyReq.setTimeout(options.proxyTimeout, function() { - proxyReq.abort(); + if (options.proxyTimeoutCustomError) { + var timeoutError = new Error('The proxy request timed out'); + timeoutError.code = 'ETIMEDOUT'; + return proxyReq.destroy(timeoutError); + } + proxyReq.destroy(); }); } diff --git a/test/lib-http-proxy-passes-web-incoming-test.js b/test/lib-http-proxy-passes-web-incoming-test.js index f6553d300..53077805a 100644 --- a/test/lib-http-proxy-passes-web-incoming-test.js +++ b/test/lib-http-proxy-passes-web-incoming-test.js @@ -287,6 +287,41 @@ describe('#createProxyServer.web() using own http server', function () { }, function() {}).end(); }); + it('should proxy the request with custom timeout errors (proxyTimeoutCustomError)', function(done) { + var proxy = httpProxy.createProxyServer({ + target: 'http://127.0.0.1:45002', + proxyTimeout: 100, + proxyTimeoutCustomError: true + }); + + require('net').createServer().listen(45002); + + var proxyServer = http.createServer(requestHandler); + + var started = new Date().getTime(); + function requestHandler(req, res) { + proxy.once('error', function (err, errReq, errRes) { + proxyServer.close(); + expect(err).to.be.an(Error); + expect(errReq).to.be.equal(req); + expect(errRes).to.be.equal(res); + expect(new Date().getTime() - started).to.be.greaterThan(99); + expect(err.code).to.be('ETIMEDOUT'); + done(); + }); + + proxy.web(req, res); + } + + proxyServer.listen('8087'); + + http.request({ + hostname: '127.0.0.1', + port: '8087', + method: 'GET', + }, function() {}).end(); + }); + it('should proxy the request and handle timeout error', function(done) { var proxy = httpProxy.createProxyServer({ target: 'http://127.0.0.1:45001',