summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/request/main.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/request/main.js')
-rw-r--r--deps/npm/node_modules/request/main.js158
1 files changed, 127 insertions, 31 deletions
diff --git a/deps/npm/node_modules/request/main.js b/deps/npm/node_modules/request/main.js
index 5c14264163..f651202740 100644
--- a/deps/npm/node_modules/request/main.js
+++ b/deps/npm/node_modules/request/main.js
@@ -26,6 +26,7 @@ var http = require('http')
, Cookie = require('./vendor/cookie')
, CookieJar = require('./vendor/cookie/jar')
, cookieJar = new CookieJar
+ , tunnel = require('./tunnel')
;
if (process.logging) {
@@ -133,6 +134,20 @@ Request.prototype.init = function (options) {
}
if (self.proxy) {
if (typeof self.proxy == 'string') self.proxy = url.parse(self.proxy)
+
+ // do the HTTP CONNECT dance using koichik/node-tunnel
+ if (http.globalAgent && self.uri.protocol === "https:") {
+ self.tunnel = true
+ var tunnelFn = self.proxy.protocol === "http:"
+ ? tunnel.httpsOverHttp : tunnel.httpsOverHttps
+
+ var tunnelOptions = { proxy: { host: self.proxy.hostname
+ , port: +self.proxy.port }
+ , ca: this.ca }
+
+ self.agent = tunnelFn(tunnelOptions)
+ self.tunnel = true
+ }
}
self._redirectsFollowed = self._redirectsFollowed || 0
@@ -163,7 +178,7 @@ Request.prototype.init = function (options) {
else if (self.uri.protocol == 'https:') {self.uri.port = 443}
}
- if (self.proxy) {
+ if (self.proxy && !self.tunnel) {
self.port = self.proxy.port
self.host = self.proxy.hostname
} else {
@@ -177,9 +192,12 @@ Request.prototype.init = function (options) {
}
self.clientErrorHandler = function (error) {
+ if (self._aborted) return
+
if (self.setHost) delete self.headers.host
- if (self.req._reusedSocket && error.code === 'ECONNRESET') {
- self.agent = {addRequest: ForeverAgent.prototype.addRequestNoreuse.bind(self.agent)}
+ if (self.req._reusedSocket && error.code === 'ECONNRESET'
+ && self.agent.addRequestNoreuse) {
+ self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) }
self.start()
self.req.end()
return
@@ -204,7 +222,7 @@ Request.prototype.init = function (options) {
if (self.uri.auth && !self.headers.authorization) {
self.headers.authorization = "Basic " + toBase64(self.uri.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':'))
}
- if (self.proxy && self.proxy.auth && !self.headers['proxy-authorization']) {
+ if (self.proxy && self.proxy.auth && !self.headers['proxy-authorization'] && !self.tunnel) {
self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':'))
}
@@ -218,7 +236,7 @@ Request.prototype.init = function (options) {
if (self.path.length === 0) self.path = '/'
- if (self.proxy) self.path = (self.uri.protocol + '//' + self.uri.host + self.path)
+ if (self.proxy && !self.tunnel) self.path = (self.uri.protocol + '//' + self.uri.host + self.path)
if (options.json) {
self.json(options.json)
@@ -247,7 +265,7 @@ Request.prototype.init = function (options) {
}
}
- var protocol = self.proxy ? self.proxy.protocol : self.uri.protocol
+ var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol
, defaultModules = {'http:':http, 'https:':https}
, httpModules = self.httpModules || {}
;
@@ -255,17 +273,30 @@ Request.prototype.init = function (options) {
if (!self.httpModule) throw new Error("Invalid protocol")
+ if (options.ca) self.ca = options.ca
+
+ if (!self.agent) {
+ if (options.agentOptions) self.agentOptions = options.agentOptions
+
+ if (options.agentClass) {
+ self.agentClass = options.agentClass
+ } else if (options.forever) {
+ self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL
+ } else {
+ self.agentClass = self.httpModule.Agent
+ }
+ }
+
if (self.pool === false) {
self.agent = false
} else {
+ self.agent = self.agent || self.getAgent()
if (self.maxSockets) {
// Don't use our pooling if node has the refactored client
- self.agent = self.agent || self.httpModule.globalAgent || self.getAgent(self.host, self.port)
self.agent.maxSockets = self.maxSockets
}
if (self.pool.maxSockets) {
// Don't use our pooling if node has the refactored client
- self.agent = self.agent || self.httpModule.globalAgent || self.getAgent(self.host, self.port)
self.agent.maxSockets = self.pool.maxSockets
}
}
@@ -295,6 +326,8 @@ Request.prototype.init = function (options) {
})
process.nextTick(function () {
+ if (self._aborted) return
+
if (self.body) {
if (Array.isArray(self.body)) {
self.body.forEach(function(part) {
@@ -314,19 +347,61 @@ Request.prototype.init = function (options) {
self.ntick = true
})
}
-Request.prototype.getAgent = function (host, port) {
- if (!this.pool[host+':'+port]) {
- this.pool[host+':'+port] = new this.httpModule.Agent({host:host, port:port})
+
+Request.prototype.getAgent = function () {
+ var Agent = this.agentClass
+ var options = {}
+ if (this.agentOptions) {
+ for (var i in this.agentOptions) {
+ options[i] = this.agentOptions[i]
+ }
+ }
+ if (this.ca) options.ca = this.ca
+
+ var poolKey = ''
+
+ // different types of agents are in different pools
+ if (Agent !== this.httpModule.Agent) {
+ poolKey += Agent.name
+ }
+
+ if (!this.httpModule.globalAgent) {
+ // node 0.4.x
+ options.host = this.host
+ options.port = this.port
+ if (poolKey) poolKey += ':'
+ poolKey += this.host + ':' + this.port
}
- return this.pool[host+':'+port]
+
+ if (options.ca) {
+ if (poolKey) poolKey += ':'
+ poolKey += options.ca
+ }
+
+ if (!poolKey && Agent === this.httpModule.Agent && this.httpModule.globalAgent) {
+ // not doing anything special. Use the globalAgent
+ return this.httpModule.globalAgent
+ }
+
+ // already generated an agent for this setting
+ if (this.pool[poolKey]) return this.pool[poolKey]
+
+ return this.pool[poolKey] = new Agent(options)
}
+
Request.prototype.start = function () {
var self = this
+
+ if (self._aborted) return
+
self._started = true
self.method = self.method || 'GET'
self.href = self.uri.href
if (log) log('%method %href', self)
self.req = self.httpModule.request(self, function (response) {
+ if (self._aborted) return
+ if (self._paused) response.pause()
+
self.response = response
response.request = self
@@ -353,7 +428,7 @@ Request.prototype.start = function () {
if (response.statusCode >= 300 && response.statusCode < 400 &&
(self.followAllRedirects ||
- (self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST'))) &&
+ (self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST' && self.method !== 'DELETE'))) &&
response.headers.location) {
if (self._redirectsFollowed >= self.maxRedirects) {
self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop."))
@@ -423,6 +498,8 @@ Request.prototype.start = function () {
bodyLen += chunk.length
})
self.on("end", function () {
+ if (self._aborted) return
+
if (buffer.length && Buffer.isBuffer(buffer[0])) {
var body = new Buffer(bodyLen)
var i = 0
@@ -439,7 +516,7 @@ Request.prototype.start = function () {
response.body = buffer.join('')
}
- if (self.json) {
+ if (self._json) {
try {
response.body = JSON.parse(response.body)
} catch (e) {}
@@ -461,20 +538,36 @@ Request.prototype.start = function () {
// Set additional timeout on socket - in case if remote
// server freeze after sending headers
- self.req.setTimeout(self.timeout, function(){
- if (self.req) {
- self.req.abort()
- var e = new Error("ESOCKETTIMEDOUT")
- e.code = "ESOCKETTIMEDOUT"
- self.emit("error", e)
- }
- });
+ if (self.req.setTimeout) { // only works on node 0.6+
+ self.req.setTimeout(self.timeout, function(){
+ if (self.req) {
+ self.req.abort()
+ var e = new Error("ESOCKETTIMEDOUT")
+ e.code = "ESOCKETTIMEDOUT"
+ self.emit("error", e)
+ }
+ })
+ }
}
self.req.on('error', self.clientErrorHandler)
self.emit('request', self.req)
}
+
+Request.prototype.abort = function() {
+ this._aborted = true;
+
+ if (this.req) {
+ this.req.abort()
+ }
+ else if (this.response) {
+ this.response.abort()
+ }
+
+ this.emit("abort")
+}
+
Request.prototype.pipeDest = function (dest) {
var response = this.response
// Called after the response is received
@@ -554,6 +647,7 @@ Request.prototype.multipart = function (multipart) {
Request.prototype.json = function (val) {
this.setHeader('content-type', 'application/json')
this.setHeader('accept', 'application/json')
+ this._json = true
if (typeof val === 'boolean') {
if (typeof this.body === 'object') this.body = JSON.stringify(this.body)
} else {
@@ -659,22 +753,20 @@ Request.prototype.pipe = function (dest, opts) {
}
Request.prototype.write = function () {
if (!this._started) this.start()
- if (!this.req) throw new Error("This request has been piped before http.request() was called.")
this.req.write.apply(this.req, arguments)
}
Request.prototype.end = function (chunk) {
if (chunk) this.write(chunk)
if (!this._started) this.start()
- if (!this.req) throw new Error("This request has been piped before http.request() was called.")
this.req.end()
}
Request.prototype.pause = function () {
- if (!this.response) throw new Error("This request has been piped before http.request() was called.")
- this.response.pause.apply(this.response, arguments)
+ if (!this.response) this._paused = true
+ else this.response.pause.apply(this.response, arguments)
}
Request.prototype.resume = function () {
- if (!this.response) throw new Error("This request has been piped before http.request() was called.")
- this.response.resume.apply(this.response, arguments)
+ if (!this.response) this._paused = false
+ else this.response.resume.apply(this.response, arguments)
}
Request.prototype.destroy = function () {
if (!this._ended) this.end()
@@ -735,12 +827,13 @@ request.defaults = function (options) {
request.forever = function (agentOptions, optionsArg) {
var options = {}
- if (agentOptions) {
+ if (optionsArg) {
for (option in optionsArg) {
options[option] = optionsArg[option]
}
}
- options.agent = new ForeverAgent(agentOptions)
+ if (agentOptions) options.agentOptions = agentOptions
+ options.forever = true
return request.defaults(options)
}
@@ -758,7 +851,10 @@ request.put = function (uri, options, callback) {
request.head = function (uri, options, callback) {
var params = initParams(uri, options, callback);
params.options.method = 'HEAD'
- if (options.body || options.requestBodyStream || options.json || options.multipart) {
+ if (params.options.body ||
+ params.options.requestBodyStream ||
+ (params.options.json && typeof params.options.json !== 'boolean') ||
+ params.options.multipart) {
throw new Error("HTTP HEAD requests MUST NOT include a request body.")
}
return request(params.uri, params.options, params.callback)