request
Advanced tools
Comparing version 2.9.203 to 2.10.0
115
main.js
@@ -110,3 +110,3 @@ // Copyright 2010-2012 Mikeal Rogers | ||
if (!options) options = {} | ||
if (process.env.NODE_DEBUG && /request/.test(process.env.NODE_DEBUG)) console.error('REQUEST', options) | ||
if (!self.pool && self.pool !== false) self.pool = globalPool | ||
@@ -144,3 +144,2 @@ self.dests = [] | ||
if (http.globalAgent && self.uri.protocol === "https:") { | ||
self.tunnel = true | ||
var tunnelFn = self.proxy.protocol === "http:" | ||
@@ -150,3 +149,3 @@ ? tunnel.httpsOverHttp : tunnel.httpsOverHttps | ||
var tunnelOptions = { proxy: { host: self.proxy.hostname | ||
, port: +self.proxy.port | ||
, port: +self.proxy.port | ||
, proxyAuth: self.proxy.auth } | ||
@@ -325,3 +324,3 @@ , ca: this.ca } | ||
self.once('pipe', function (src) { | ||
if (self.ntick) throw new Error("You cannot pipe to this stream after the first nextTick() after creation of the request stream.") | ||
if (self.ntick && self._started) throw new Error("You cannot pipe to this stream after the outbound request has started.") | ||
self.src = src | ||
@@ -374,2 +373,66 @@ if (isReadStream(src)) { | ||
// Must call this when following a redirect from https to http or vice versa | ||
// Attempts to keep everything as identical as possible, but update the | ||
// httpModule, Tunneling agent, and/or Forever Agent in use. | ||
Request.prototype._updateProtocol = function () { | ||
var self = this | ||
var protocol = self.uri.protocol | ||
if (protocol === 'https:') { | ||
// previously was doing http, now doing https | ||
// if it's https, then we might need to tunnel now. | ||
if (self.proxy) { | ||
self.tunnel = true | ||
var tunnelFn = self.proxy.protocol === 'http:' | ||
? tunnel.httpsOverHttp : tunnel.httpsOverHttps | ||
var tunnelOptions = { proxy: { host: self.proxy.hostname | ||
, post: +self.proxy.port | ||
, proxyAuth: self.proxy.auth } | ||
, ca: self.ca } | ||
self.agent = tunnelFn(tunnelOptions) | ||
return | ||
} | ||
self.httpModule = https | ||
switch (self.agentClass) { | ||
case ForeverAgent: | ||
self.agentClass = ForeverAgent.SSL | ||
break | ||
case http.Agent: | ||
self.agentClass = https.Agent | ||
break | ||
default: | ||
// nothing we can do. Just hope for the best. | ||
return | ||
} | ||
// if there's an agent, we need to get a new one. | ||
if (self.agent) self.agent = self.getAgent() | ||
} else { | ||
if (log) log('previously https, now http') | ||
// previously was doing https, now doing http | ||
// stop any tunneling. | ||
if (self.tunnel) self.tunnel = false | ||
self.httpModule = http | ||
switch (self.agentClass) { | ||
case ForeverAgent.SSL: | ||
self.agentClass = ForeverAgent | ||
break | ||
case https.Agent: | ||
self.agentClass = http.Agent | ||
break | ||
default: | ||
// nothing we can do. just hope for the best | ||
return | ||
} | ||
// if there's an agent, then get a new one. | ||
if (self.agent) { | ||
self.agent = null | ||
self.agent = self.getAgent() | ||
} | ||
} | ||
} | ||
Request.prototype.getAgent = function () { | ||
@@ -400,3 +463,7 @@ var Agent = this.agentClass | ||
if (options.ca) { | ||
// ca option is only relevant if proxy or destination are https | ||
var proxy = this.proxy | ||
if (typeof proxy === 'string') proxy = url.parse(proxy) | ||
var caRelevant = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:' | ||
if (options.ca && caRelevant) { | ||
if (poolKey) poolKey += ':' | ||
@@ -411,2 +478,5 @@ poolKey += options.ca | ||
// we're using a stored agent. Make sure it's protocol-specific | ||
poolKey = this.uri.protocol + poolKey | ||
// already generated an agent for this setting | ||
@@ -480,3 +550,11 @@ if (this.pool[poolKey]) return this.pool[poolKey] | ||
} | ||
self.uri = response.headers.location | ||
var uriPrev = self.uri | ||
self.uri = url.parse(response.headers.location) | ||
// handle the case where we change protocol from https to http or vice versa | ||
if (self.uri.protocol !== uriPrev.protocol) { | ||
self._updateProtocol() | ||
} | ||
self.redirects.push( | ||
@@ -670,6 +748,8 @@ { statusCode : response.statusCode | ||
console.log('boundary >> ' + self.boundary) | ||
if (!multipart.forEach) throw new Error('Argument error, options.multipart.') | ||
if (self.preambleCRLF) { | ||
self.body.push(new Buffer('\r\n')) | ||
} | ||
multipart.forEach(function (part) { | ||
@@ -759,2 +839,3 @@ var body = part.body | ||
delete oa['oauth_'+i] | ||
delete oa[i] | ||
} | ||
@@ -874,3 +955,5 @@ } | ||
request.defaults = function (options) { | ||
request.initParams = initParams; | ||
request.defaults = function (options, requester) { | ||
var def = function (method) { | ||
@@ -882,5 +965,12 @@ var d = function (uri, opts, callback) { | ||
} | ||
return method(params.options, params.callback) | ||
if(typeof requester === 'function') { | ||
if(method === request) { | ||
method = requester; | ||
} else { | ||
params.options._requester = requester; | ||
} | ||
} | ||
return method(params.options, params.callback); | ||
} | ||
return d | ||
return d; | ||
} | ||
@@ -935,2 +1025,5 @@ var de = def(request) | ||
params.options.method = 'DELETE' | ||
if(typeof params.options._requester === 'function') { | ||
request = params.options._requester; | ||
} | ||
return request(params.uri || null, params.options, params.callback) | ||
@@ -937,0 +1030,0 @@ } |
{ "name" : "request" | ||
, "description" : "Simplified HTTP request client." | ||
, "tags" : ["http", "simple", "util", "utility"] | ||
, "version" : "2.9.203" | ||
, "version" : "2.10.0" | ||
, "author" : "Mikeal Rogers <mikeal.rogers@gmail.com>" | ||
@@ -6,0 +6,0 @@ , "repository" : |
@@ -154,3 +154,3 @@ # Request -- Simplified HTTP request method | ||
* `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. | ||
* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. | ||
* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as json. | ||
* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below. | ||
@@ -157,0 +157,0 @@ * `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true. |
@@ -54,7 +54,11 @@ var fs = require('fs') | ||
req.on('end', function () { | ||
if (r !== text) console.log(r, text); | ||
assert.equal(r, text) | ||
resp.writeHead(200, {'content-type':'text/plain'}) | ||
resp.write('OK') | ||
resp.end() | ||
if (req.headers['content-type'] && req.headers['content-type'].indexOf('boundary=') >= 0) { | ||
var boundary = req.headers['content-type'].split('boundary=')[1]; | ||
text = text.replace(/__BOUNDARY__/g, boundary); | ||
} | ||
if (r !== text) console.log(r, text); | ||
assert.equal(r, text) | ||
resp.writeHead(200, {'content-type':'text/plain'}) | ||
resp.write('OK') | ||
resp.end() | ||
}) | ||
@@ -61,0 +65,0 @@ } |
@@ -53,3 +53,35 @@ var server = require('./server') | ||
} | ||
, testPutMultipart : | ||
{ resp: server.createPostValidator( | ||
'--__BOUNDARY__\r\n' + | ||
'content-type: text/html\r\n' + | ||
'\r\n' + | ||
'<html><body>Oh hi.</body></html>' + | ||
'\r\n--__BOUNDARY__\r\n\r\n' + | ||
'Oh hi.' + | ||
'\r\n--__BOUNDARY__--' | ||
) | ||
, method: "PUT" | ||
, multipart: | ||
[ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'} | ||
, {'body': 'Oh hi.'} | ||
] | ||
} | ||
, testPutMultipartPreambleCRLF : | ||
{ resp: server.createPostValidator( | ||
'\r\n--__BOUNDARY__\r\n' + | ||
'content-type: text/html\r\n' + | ||
'\r\n' + | ||
'<html><body>Oh hi.</body></html>' + | ||
'\r\n--__BOUNDARY__\r\n\r\n' + | ||
'Oh hi.' + | ||
'\r\n--__BOUNDARY__--' | ||
) | ||
, method: "PUT" | ||
, preambleCRLF: true | ||
, multipart: | ||
[ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'} | ||
, {'body': 'Oh hi.'} | ||
] | ||
} | ||
} | ||
@@ -56,0 +88,0 @@ |
@@ -64,6 +64,37 @@ var server = require('./server') | ||
counter += 1; | ||
console.log(counter.toString() + " tests passed.") | ||
s.close() | ||
}); | ||
s.on('/get_custom', function(req, resp) { | ||
assert.equal(req.headers.foo, 'bar'); | ||
assert.equal(req.headers.x, 'y'); | ||
resp.writeHead(200, {'Content-Type': 'text/plain'}); | ||
resp.end(); | ||
}); | ||
// test custom request handler function | ||
var defaultRequest = request.defaults({ | ||
headers:{foo:"bar"} | ||
, body: 'TESTING!' | ||
}, function(uri, options, callback) { | ||
var params = request.initParams(uri, options, callback); | ||
options = params.options; | ||
options.headers.x = 'y'; | ||
return request(params.uri, params.options, params.callback); | ||
}); | ||
var msg = 'defaults test failed. head request should throw earlier'; | ||
assert.throws(function() { | ||
defaultRequest.head(s.url + '/get_custom', function(e, r, b) { | ||
throw new Error(msg); | ||
}); | ||
counter+=1; | ||
}, msg); | ||
defaultRequest.get(s.url + '/get_custom', function(e, r, b) { | ||
if(e) throw e; | ||
counter += 1; | ||
console.log(counter.toString() + " tests passed."); | ||
s.close(); | ||
}); | ||
}) |
@@ -55,9 +55,9 @@ // a test where we validate the siguature of the keys | ||
{ resp: server.createPostValidator( | ||
'--frontier\r\n' + | ||
'--__BOUNDARY__\r\n' + | ||
'content-type: text/html\r\n' + | ||
'\r\n' + | ||
'<html><body>Oh hi.</body></html>' + | ||
'\r\n--frontier\r\n\r\n' + | ||
'\r\n--__BOUNDARY__\r\n\r\n' + | ||
'Oh hi.' + | ||
'\r\n--frontier--' | ||
'\r\n--__BOUNDARY__--' | ||
) | ||
@@ -64,0 +64,0 @@ , method: "PUT" |
@@ -47,9 +47,9 @@ var server = require('./server') | ||
{ resp: server.createPostValidator( | ||
'--frontier\r\n' + | ||
'--__BOUNDARY__\r\n' + | ||
'content-type: text/html\r\n' + | ||
'\r\n' + | ||
'<html><body>Oh hi.</body></html>' + | ||
'\r\n--frontier\r\n\r\n' + | ||
'\r\n--__BOUNDARY__\r\n\r\n' + | ||
'Oh hi.' + | ||
'\r\n--frontier--' | ||
'\r\n--__BOUNDARY__--' | ||
) | ||
@@ -56,0 +56,0 @@ , method: "PUT" |
@@ -53,9 +53,9 @@ var server = require('./server') | ||
{ resp: server.createPostValidator( | ||
'--frontier\r\n' + | ||
'--__BOUNDARY__\r\n' + | ||
'content-type: text/html\r\n' + | ||
'\r\n' + | ||
'<html><body>Oh hi.</body></html>' + | ||
'\r\n--frontier\r\n\r\n' + | ||
'\r\n--__BOUNDARY__\r\n\r\n' + | ||
'Oh hi.' + | ||
'\r\n--frontier--' | ||
'\r\n--__BOUNDARY__--' | ||
) | ||
@@ -62,0 +62,0 @@ , method: "PUT" |
@@ -35,5 +35,6 @@ // test that we can tunnel a https request over an http proxy | ||
squid.on('exit', function (c) { | ||
console.error('exit '+c) | ||
console.error('squid: exit '+c) | ||
if (c && !ready) { | ||
console.error('squid must be installed to run this test.') | ||
console.error('skipping this test. please install squid and run again if you need to test tunneling.') | ||
c = null | ||
@@ -40,0 +41,0 @@ hadError = null |
180302
52
3338
10