diff --git a/README.md b/README.md index d0a1a2a91..95ba8659e 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ You can still use intermediate proxies, the requests will still follow HTTP forw If you specify a `proxy` option, then the request (and any subsequent redirects) will be sent via a connection to the proxy server. -If your endpoint is an `https` url, and you are using a proxy, then +If your endpoint is an `https` url, the `tunnel` option is not `false`, and you are using a proxy, then request will send a `CONNECT` request to the proxy server *first*, and then use the supplied connection to connect to the endpoint. @@ -607,10 +607,7 @@ The first argument can be either a `url` or an `options` object. The only requir * `httpSignature` - Options for the [HTTP Signature Scheme](https://github.com/joyent/node-http-signature/blob/master/http_signing.md) using [Joyent's library](https://github.com/joyent/node-http-signature). The `keyId` and `key` properties must be specified. See the docs for other options. * `localAddress` - Local interface to bind for network connections. * `gzip` - If `true`, add an `Accept-Encoding` header to request compressed content encodings from the server (if not already present) and decode supported content encodings in the response. **Note:** Automatic decoding of the response content is performed on the body data returned through `request` (both through the `request` stream and passed to the callback function) but is not performed on the `response` stream (available from the `response` event) which is the unmodified `http.IncomingMessage` object which may contain compressed data. See example below. -* `tunnel` - If `true`, then *always* use a tunneling proxy. If - `false` (default), then tunneling will only be used if the - destination is `https`, or if a previous request in the redirect - chain used a tunneling proxy. +* `tunnel` - If `true`, then *always* use a tunneling proxy. If `false`, then tunneling will only be used if a previous request in the redirect chain used a tunneling proxy. If not set, then tunneling will only be used if the destination is `https`, or if a previous request in the redirect chain used a tunneling proxy. * `proxyHeaderWhiteList` - A whitelist of headers to send to a tunneling proxy. * `proxyHeaderExclusiveList` - A whitelist of headers to send diff --git a/request.js b/request.js index 6bdd51436..ee120ccf2 100644 --- a/request.js +++ b/request.js @@ -283,6 +283,8 @@ function Request (options) { self.writable = true if (typeof options.tunnel === 'undefined') { options.tunnel = false + } else { + self.explicitTunnel = true } if (options.method) { self.explicitMethod = true @@ -308,7 +310,7 @@ Request.prototype.setupTunnel = function () { return false } - if (!self.tunnel && self.uri.protocol !== 'https:') { + if (!self.tunnel && (self.explicitTunnel === true || self.uri.protocol !== 'https:')) { return false } @@ -738,7 +740,7 @@ Request.prototype._updateProtocol = function () { var self = this var protocol = self.uri.protocol - if (protocol === 'https:' || self.tunnel) { + if ((self.explicitTunnel !== true && protocol === 'https:') || self.tunnel) { // previously was doing http, now doing https // if it's https, then we might need to tunnel now. if (self.proxy) { diff --git a/tests/test-proxy.js b/tests/test-proxy.js index 12c5f9666..f8ba6d3a8 100644 --- a/tests/test-proxy.js +++ b/tests/test-proxy.js @@ -7,11 +7,13 @@ var server = require('./server') var s = server.createServer() , currResponseHandler -s.on('http://google.com/', function(req, res) { +function handleRequest(req, res) { currResponseHandler(req, res) res.writeHeader(200) res.end('ok') -}) +} +s.on('http://google.com/', handleRequest) +s.on('https://google.com/', handleRequest) var proxyEnvVars = [ 'http_proxy', @@ -234,6 +236,12 @@ if (process.env.TEST_PROXY_HARNESS) { t.equal(req.headers['proxy-authorization'], undefined) t.equal(req.headers.authorization, 'Basic dXNlcjpwYXNz') }) + + runTest('proxy https over http without tunneling', { + url : 'https://google.com', + proxy : s.url, + tunnel : false + }, true) }