Comparing version 2.9.152 to 2.9.153
module.exports = ForeverAgent | ||
ForeverAgent.SSL = ForeverAgentSSL | ||
@@ -6,2 +7,4 @@ var util = require('util') | ||
, net = require('net') | ||
, tls = require('tls') | ||
, AgentSSL = require('https').Agent | ||
@@ -38,3 +41,3 @@ function ForeverAgent(options) { | ||
}) | ||
self.createConnection = net.createConnection | ||
} | ||
@@ -45,2 +48,4 @@ util.inherits(ForeverAgent, Agent) | ||
ForeverAgent.prototype.createConnection = net.createConnection | ||
ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest | ||
@@ -88,1 +93,15 @@ ForeverAgent.prototype.addRequest = function(req, host, port) { | ||
} | ||
function ForeverAgentSSL (options) { | ||
ForeverAgent.call(this, options) | ||
} | ||
util.inherits(ForeverAgentSSL, ForeverAgent) | ||
ForeverAgentSSL.prototype.createConnection = createConnectionSSL | ||
ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest | ||
function createConnectionSSL (port, host, options) { | ||
options.port = port | ||
options.host = host | ||
return tls.connect(options) | ||
} |
130
main.js
@@ -29,2 +29,3 @@ // Copyright 2010-2012 Mikeal Rogers | ||
, cookieJar = new CookieJar | ||
, tunnel = require('./tunnel') | ||
; | ||
@@ -137,2 +138,16 @@ | ||
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 | ||
} | ||
} | ||
@@ -168,3 +183,3 @@ | ||
if (self.proxy) { | ||
if (self.proxy && !self.tunnel) { | ||
self.port = self.proxy.port | ||
@@ -186,4 +201,5 @@ self.host = self.proxy.hostname | ||
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() | ||
@@ -213,3 +229,3 @@ self.req.end() | ||
} | ||
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(':')) | ||
@@ -228,3 +244,3 @@ } | ||
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) | ||
@@ -258,3 +274,3 @@ if (options.json) { | ||
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} | ||
@@ -267,8 +283,22 @@ , httpModules = self.httpModules || {} | ||
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 | ||
@@ -278,3 +308,2 @@ } | ||
// 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 | ||
@@ -330,8 +359,44 @@ } | ||
} | ||
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] | ||
} | ||
} | ||
return this.pool[host+':'+port] | ||
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 | ||
} | ||
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 () { | ||
@@ -348,2 +413,3 @@ var self = this | ||
if (self._aborted) return | ||
if (self._paused) response.pause() | ||
@@ -376,3 +442,3 @@ self.response = response | ||
(self.followAllRedirects || | ||
(self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST'))) && | ||
(self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST' && self.method !== 'DELETE'))) && | ||
response.headers.location) { | ||
@@ -487,10 +553,12 @@ if (self._redirectsFollowed >= self.maxRedirects) { | ||
// 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) | ||
} | ||
}) | ||
} | ||
} | ||
@@ -701,3 +769,2 @@ | ||
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) | ||
@@ -708,12 +775,11 @@ } | ||
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) | ||
} | ||
@@ -779,3 +845,3 @@ Request.prototype.destroy = function () { | ||
var options = {} | ||
if (agentOptions) { | ||
if (optionsArg) { | ||
for (option in optionsArg) { | ||
@@ -785,3 +851,4 @@ options[option] = optionsArg[option] | ||
} | ||
options.agent = new ForeverAgent(agentOptions) | ||
if (agentOptions) options.agentOptions = agentOptions | ||
options.forever = true | ||
return request.defaults(options) | ||
@@ -804,3 +871,6 @@ } | ||
params.options.method = 'HEAD' | ||
if (params.options.body || params.options.requestBodyStream || params.options.json || params.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.") | ||
@@ -807,0 +877,0 @@ } |
{ "name" : "request" | ||
, "description" : "Simplified HTTP request client." | ||
, "tags" : ["http", "simple", "util", "utility"] | ||
, "version" : "2.9.152" | ||
, "version" : "2.9.153" | ||
, "author" : "Mikeal Rogers <mikeal.rogers@gmail.com>" | ||
@@ -6,0 +6,0 @@ , "repository" : |
@@ -14,2 +14,3 @@ var spawn = require('child_process').spawn | ||
, 'test-https.js' | ||
, 'test-https-strict.js' | ||
, 'test-oauth.js' | ||
@@ -21,2 +22,3 @@ , 'test-pipes.js' | ||
, 'test-timeout.js' | ||
, 'test-tunnel.js' | ||
] | ||
@@ -37,2 +39,2 @@ | ||
} | ||
next() | ||
next() |
@@ -20,9 +20,16 @@ var fs = require('fs') | ||
exports.createSSLServer = function(port) { | ||
exports.createSSLServer = function(port, opts) { | ||
port = port || 16767 | ||
var options = { 'key' : fs.readFileSync(path.join(__dirname, 'ssl', 'test.key')) | ||
, 'cert': fs.readFileSync(path.join(__dirname, 'ssl', 'test.crt')) | ||
var options = { 'key' : path.join(__dirname, 'ssl', 'test.key') | ||
, 'cert': path.join(__dirname, 'ssl', 'test.crt') | ||
} | ||
if (opts) { | ||
for (var i in opts) options[i] = opts[i] | ||
} | ||
for (var i in options) { | ||
options[i] = fs.readFileSync(options[i]) | ||
} | ||
var s = https.createServer(options, function (req, resp) { | ||
@@ -29,0 +36,0 @@ s.emit(req.url, req, resp); |
@@ -115,6 +115,42 @@ var server = require('./server') | ||
// Should not follow delete redirects by default | ||
request.del(server+'/temp', { jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { | ||
try { | ||
assert.ok(hits.temp, 'Original request is to /temp') | ||
assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') | ||
assert.equal(res.statusCode, 301, 'Response is the bounce itself') | ||
passed += 1 | ||
} finally { | ||
done() | ||
} | ||
}) | ||
// Should not follow delete redirects even if followRedirect is set to true | ||
request.del(server+'/temp', { followRedirect: true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { | ||
try { | ||
assert.ok(hits.temp, 'Original request is to /temp') | ||
assert.ok(!hits.temp_landing, 'No chasing the redirect when delete') | ||
assert.equal(res.statusCode, 301, 'Response is the bounce itself') | ||
passed += 1 | ||
} finally { | ||
done() | ||
} | ||
}) | ||
// Should follow delete redirects when followAllRedirects true | ||
request.del(server+'/temp', {followAllRedirects:true, jar: jar, headers: {cookie: 'foo=bar'}}, function (er, res, body) { | ||
try { | ||
assert.ok(hits.temp, 'Original request is to /temp') | ||
assert.ok(hits.temp_landing, 'Forward to temporary landing URL') | ||
assert.equal(body, 'temp_landing', 'Got temporary landing content') | ||
passed += 1 | ||
} finally { | ||
done() | ||
} | ||
}) | ||
var reqs_done = 0; | ||
function done() { | ||
reqs_done += 1; | ||
if(reqs_done == 6) { | ||
if(reqs_done == 9) { | ||
console.log(passed + ' tests passed.') | ||
@@ -121,0 +157,0 @@ s.close() |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
156013
46
2744
8
18