diff options
author | isaacs <i@izs.me> | 2012-02-25 06:27:39 +0400 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-02-25 06:27:39 +0400 |
commit | 6bbbff09a8e1aaac7520244d53e9bb29f90939b6 (patch) | |
tree | 30f2eecad688bab0736306ac13dd1905fea14e3c | |
parent | 61da7a3cf9608015333bac2387dfeab7cd15fb35 (diff) |
update request to 2.9.151
-rw-r--r-- | node_modules/request/README.md | 4 | ||||
-rw-r--r-- | node_modules/request/main.js | 736 | ||||
-rw-r--r-- | node_modules/request/mimetypes.js | 10 | ||||
-rw-r--r-- | node_modules/request/oauth.js | 2 | ||||
-rw-r--r-- | node_modules/request/package.json | 4 |
5 files changed, 445 insertions, 311 deletions
diff --git a/node_modules/request/README.md b/node_modules/request/README.md index 4ea89f794..e5839b50e 100644 --- a/node_modules/request/README.md +++ b/node_modules/request/README.md @@ -38,7 +38,7 @@ request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png')) You can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers. ```javascript -fs.readStream('file.json').pipe(request.put('http://mysite.com/obj.json')) +fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json')) ``` Request can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers. @@ -146,6 +146,7 @@ request.post({url:url, oauth:oauth}, function (e, r, body) { The first argument can be either a url or an options object. The only required option is uri, all others are optional. * `uri` || `url` - fully qualified uri or a parsed url object from url.parse() +* `qs` - object containing querystring values to be appended to the uri * `method` - http method, defaults to GET * `headers` - http headers, defaults to {} * `body` - entity body for POST and PUT requests. Must be buffer or string. @@ -153,6 +154,7 @@ The first argument can be either a url or an options object. The only required o * `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. * `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below. * `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true. +* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false. * `maxRedirects` - the maximum number of redirects to follow, defaults to 10. * `onResponse` - If true the callback will be fired on the "response" event instead of "end". If a function it will be called on "response" and not effect the regular semantics of the main callback on "end". * `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer. diff --git a/node_modules/request/main.js b/node_modules/request/main.js index a25393ec3..5c1426416 100644 --- a/node_modules/request/main.js +++ b/node_modules/request/main.js @@ -1,4 +1,4 @@ -// Copyright 2010-2011 Mikeal Rogers +// Copyright 2010-2012 Mikeal Rogers // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -67,7 +67,9 @@ function isReadStream (rs) { function copy (obj) { var o = {} - for (var i in obj) o[i] = obj[i] + Object.keys(obj).forEach(function (i) { + o[i] = obj[i] + }) return o } @@ -83,24 +85,31 @@ function Request (options) { if (typeof options === 'string') { options = {uri:options} } - + + var reserved = Object.keys(Request.prototype) for (var i in options) { - this[i] = options[i] + if (reserved.indexOf(i) === -1) { + this[i] = options[i] + } else { + if (typeof options[i] === 'function') { + delete options[i] + } + } } - if (!this.pool) this.pool = globalPool - this.dests = [] - this.__isRequestRequest = true + options = copy(options) + + this.init(options) } util.inherits(Request, stream.Stream) -Request.prototype.getAgent = function (host, port) { - if (!this.pool[host+':'+port]) { - this.pool[host+':'+port] = new this.httpModule.Agent({host:host, port:port}) - } - return this.pool[host+':'+port] -} -Request.prototype.request = function () { +Request.prototype.init = function (options) { var self = this - + + if (!options) options = {} + + if (!self.pool) self.pool = globalPool + self.dests = [] + self.__isRequestRequest = true + // Protect against double callback if (!self._callback && self.callback) { self._callback = self.callback @@ -129,12 +138,13 @@ Request.prototype.request = function () { self._redirectsFollowed = self._redirectsFollowed || 0 self.maxRedirects = (self.maxRedirects !== undefined) ? self.maxRedirects : 10 self.followRedirect = (self.followRedirect !== undefined) ? self.followRedirect : true - if (self.followRedirect) + self.followAllRedirects = (self.followAllRedirects !== undefined) ? self.followAllRedirects : false; + if (self.followRedirect || self.followAllRedirects) self.redirects = self.redirects || [] self.headers = self.headers ? copy(self.headers) : {} - var setHost = false + self.setHost = false if (!self.headers.host) { self.headers.host = self.uri.hostname if (self.uri.port) { @@ -142,27 +152,10 @@ Request.prototype.request = function () { !(self.uri.port === 443 && self.uri.protocol === 'https:') ) self.headers.host += (':'+self.uri.port) } - setHost = true - } - - if (self.jar === false) { - // disable cookies - var cookies = false; - self._disableCookies = true; - } else if (self.jar) { - // fetch cookie from the user defined cookie jar - var cookies = self.jar.get({ url: self.uri.href }) - } else { - // fetch cookie from the global cookie jar - var cookies = cookieJar.get({ url: self.uri.href }) - } - if (cookies) { - var cookieString = cookies.map(function (c) { - return c.name + "=" + c.value; - }).join("; "); - - self.headers.Cookie = cookieString; + self.setHost = true } + + self.jar(options.jar) if (!self.uri.pathname) {self.uri.pathname = '/'} if (!self.uri.port) { @@ -183,65 +176,29 @@ Request.prototype.request = function () { delete self.callback } - var clientErrorHandler = function (error) { - if (setHost) delete self.headers.host + self.clientErrorHandler = function (error) { + if (self.setHost) delete self.headers.host if (self.req._reusedSocket && error.code === 'ECONNRESET') { self.agent = {addRequest: ForeverAgent.prototype.addRequestNoreuse.bind(self.agent)} self.start() self.req.end() return } - if (self.timeout && self.timeoutTimer) clearTimeout(self.timeoutTimer) + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer); + self.timeoutTimer = null; + } self.emit('error', error) } if (self.onResponse) self.on('error', function (e) {self.onResponse(e)}) if (self.callback) self.on('error', function (e) {self.callback(e)}) - if (self.form) { - self.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8' - self.body = qs.stringify(self.form).toString('utf8') - } - - if (self.oauth) { - var form - if (self.headers['content-type'] && - self.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) === - 'application/x-www-form-urlencoded' - ) { - form = qs.parse(self.body) - } - if (self.uri.query) { - form = qs.parse(self.uri.query) - } - if (!form) form = {} - var oa = {} - for (var i in form) oa[i] = form[i] - for (var i in self.oauth) oa['oauth_'+i] = self.oauth[i] - if (!oa.oauth_version) oa.oauth_version = '1.0' - if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( (new Date()).getTime() / 1000 ).toString() - if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '') - - oa.oauth_signature_method = 'HMAC-SHA1' - - var consumer_secret = oa.oauth_consumer_secret - delete oa.oauth_consumer_secret - var token_secret = oa.oauth_token_secret - delete oa.oauth_token_secret - - var baseurl = self.uri.protocol + '//' + self.uri.host + self.uri.pathname - var signature = oauth.hmacsign(self.method, baseurl, oa, consumer_secret, token_secret) - - // oa.oauth_signature = signature - for (var i in form) { - if ( i.slice(0, 'oauth_') in self.oauth) { - // skip - } else { - delete oa['oauth_'+i] - } - } - self.headers.authorization = - 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',') - self.headers.authorization += ',oauth_signature="'+oauth.rfc3986(signature)+'"' + if (options.form) { + self.form(options.form) + } + + if (options.oauth) { + self.oauth(options.oauth) } if (self.uri.auth && !self.headers.authorization) { @@ -251,6 +208,8 @@ Request.prototype.request = function () { self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) } + if (options.qs) self.qs(options.qs) + if (self.uri.path) { self.path = self.uri.path } else { @@ -261,39 +220,10 @@ Request.prototype.request = function () { if (self.proxy) self.path = (self.uri.protocol + '//' + self.uri.host + self.path) - if (self.json) { - self.headers['content-type'] = 'application/json' - if (typeof self.json === 'boolean') { - if (typeof self.body === 'object') self.body = JSON.stringify(self.body) - } else { - self.body = JSON.stringify(self.json) - } - - } else if (self.multipart) { - self.body = [] - - if (!self.headers['content-type']) { - self.headers['content-type'] = 'multipart/related;boundary="frontier"'; - } else { - self.headers['content-type'] = self.headers['content-type'].split(';')[0] + ';boundary="frontier"'; - } - - if (!self.multipart.forEach) throw new Error('Argument error, options.multipart.') - - self.multipart.forEach(function (part) { - var body = part.body - if(!body) throw Error('Body attribute missing in multipart.') - delete part.body - var preamble = '--frontier\r\n' - Object.keys(part).forEach(function(key){ - preamble += key + ': ' + part[key] + '\r\n' - }) - preamble += '\r\n' - self.body.push(new Buffer(preamble)) - self.body.push(new Buffer(body)) - self.body.push(new Buffer('\r\n')) - }) - self.body.push(new Buffer('--frontier--')) + if (options.json) { + self.json(options.json) + } else if (options.multipart) { + self.multipart(options.multipart) } if (self.body) { @@ -340,162 +270,6 @@ Request.prototype.request = function () { } } - self.start = function () { - 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) { - self.response = response - response.request = self - - if (self.httpModule === https && - self.strictSSL && - !response.client.authorized) { - var sslErr = response.client.authorizationError - self.emit('error', new Error('SSL Error: '+ sslErr)) - return - } - - if (setHost) delete self.headers.host - if (self.timeout && self.timeoutTimer) clearTimeout(self.timeoutTimer) - - if (response.headers['set-cookie'] && (!self._disableCookies)) { - response.headers['set-cookie'].forEach(function(cookie) { - if (self.jar) self.jar.add(new Cookie(cookie)) - else cookieJar.add(new Cookie(cookie)) - }) - } - - if (response.statusCode >= 300 && - response.statusCode < 400 && - self.followRedirect && - self.method !== 'PUT' && - self.method !== 'POST' && - response.headers.location) { - if (self._redirectsFollowed >= self.maxRedirects) { - self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop.")) - return - } - self._redirectsFollowed += 1 - - if (!isUrl.test(response.headers.location)) { - response.headers.location = url.resolve(self.uri.href, response.headers.location) - } - self.uri = response.headers.location - self.redirects.push( - { statusCode : response.statusCode - , redirectUri: response.headers.location - } - ) - delete self.req - delete self.agent - delete self._started - if (self.headers) { - delete self.headers.host - } - if (log) log('Redirect to %uri', self) - request(self, self.callback) - return // Ignore the rest of the response - } else { - self._redirectsFollowed = self._redirectsFollowed || 0 - // Be a good stream and emit end when the response is finished. - // Hack to emit end on close because of a core bug that never fires end - response.on('close', function () { - if (!self._ended) self.response.emit('end') - }) - - if (self.encoding) { - if (self.dests.length !== 0) { - console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") - } else { - response.setEncoding(self.encoding) - } - } - - self.pipeDest = function (dest) { - if (dest.headers) { - dest.headers['content-type'] = response.headers['content-type'] - if (response.headers['content-length']) { - dest.headers['content-length'] = response.headers['content-length'] - } - } - if (dest.setHeader) { - for (var i in response.headers) { - dest.setHeader(i, response.headers[i]) - } - dest.statusCode = response.statusCode - } - if (self.pipefilter) self.pipefilter(response, dest) - } - - self.dests.forEach(function (dest) { - self.pipeDest(dest) - }) - - response.on("data", function (chunk) { - self._destdata = true - self.emit("data", chunk) - }) - response.on("end", function (chunk) { - self._ended = true - self.emit("end", chunk) - }) - response.on("close", function () {self.emit("close")}) - - self.emit('response', response) - - if (self.onResponse) { - self.onResponse(null, response) - } - if (self.callback) { - var buffer = [] - var bodyLen = 0 - self.on("data", function (chunk) { - buffer.push(chunk) - bodyLen += chunk.length - }) - self.on("end", function () { - if (buffer.length && Buffer.isBuffer(buffer[0])) { - var body = new Buffer(bodyLen) - var i = 0 - buffer.forEach(function (chunk) { - chunk.copy(body, i, 0, chunk.length) - i += chunk.length - }) - if (self.encoding === null) { - response.body = body - } else { - response.body = body.toString() - } - } else if (buffer.length) { - response.body = buffer.join('') - } - - if (self.json) { - try { - response.body = JSON.parse(response.body) - } catch (e) {} - } - - self.callback(null, response, response.body) - }) - } - } - }) - - if (self.timeout && !self.timeoutTimer) { - self.timeoutTimer = setTimeout(function() { - self.req.abort() - var e = new Error("ETIMEDOUT") - e.code = "ETIMEDOUT" - self.emit("error", e) - }, self.timeout) - } - - self.req.on('error', clientErrorHandler) - } - 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.") self.src = src @@ -540,20 +314,346 @@ Request.prototype.request = function () { self.ntick = true }) } -Request.prototype.pipe = function (dest) { +Request.prototype.getAgent = function (host, port) { + if (!this.pool[host+':'+port]) { + this.pool[host+':'+port] = new this.httpModule.Agent({host:host, port:port}) + } + return this.pool[host+':'+port] +} +Request.prototype.start = function () { + var self = this + 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) { + self.response = response + response.request = self + + if (self.httpModule === https && + self.strictSSL && + !response.client.authorized) { + var sslErr = response.client.authorizationError + self.emit('error', new Error('SSL Error: '+ sslErr)) + return + } + + if (self.setHost) delete self.headers.host + if (self.timeout && self.timeoutTimer) { + clearTimeout(self.timeoutTimer); + self.timeoutTimer = null; + } + + if (response.headers['set-cookie'] && (!self._disableCookies)) { + response.headers['set-cookie'].forEach(function(cookie) { + if (self._jar) self._jar.add(new Cookie(cookie)) + else cookieJar.add(new Cookie(cookie)) + }) + } + + if (response.statusCode >= 300 && response.statusCode < 400 && + (self.followAllRedirects || + (self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST'))) && + response.headers.location) { + if (self._redirectsFollowed >= self.maxRedirects) { + self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop.")) + return + } + self._redirectsFollowed += 1 + + if (!isUrl.test(response.headers.location)) { + response.headers.location = url.resolve(self.uri.href, response.headers.location) + } + self.uri = response.headers.location + self.redirects.push( + { statusCode : response.statusCode + , redirectUri: response.headers.location + } + ) + self.method = 'GET'; // Force all redirects to use GET + delete self.req + delete self.agent + delete self._started + if (self.headers) { + delete self.headers.host + } + if (log) log('Redirect to %uri', self) + self.init() + return // Ignore the rest of the response + } else { + self._redirectsFollowed = self._redirectsFollowed || 0 + // Be a good stream and emit end when the response is finished. + // Hack to emit end on close because of a core bug that never fires end + response.on('close', function () { + if (!self._ended) self.response.emit('end') + }) + + if (self.encoding) { + if (self.dests.length !== 0) { + console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") + } else { + response.setEncoding(self.encoding) + } + } + + self.dests.forEach(function (dest) { + self.pipeDest(dest) + }) + + response.on("data", function (chunk) { + self._destdata = true + self.emit("data", chunk) + }) + response.on("end", function (chunk) { + self._ended = true + self.emit("end", chunk) + }) + response.on("close", function () {self.emit("close")}) + + self.emit('response', response) + + if (self.onResponse) { + self.onResponse(null, response) + } + if (self.callback) { + var buffer = [] + var bodyLen = 0 + self.on("data", function (chunk) { + buffer.push(chunk) + bodyLen += chunk.length + }) + self.on("end", function () { + if (buffer.length && Buffer.isBuffer(buffer[0])) { + var body = new Buffer(bodyLen) + var i = 0 + buffer.forEach(function (chunk) { + chunk.copy(body, i, 0, chunk.length) + i += chunk.length + }) + if (self.encoding === null) { + response.body = body + } else { + response.body = body.toString() + } + } else if (buffer.length) { + response.body = buffer.join('') + } + + if (self.json) { + try { + response.body = JSON.parse(response.body) + } catch (e) {} + } + + self.callback(null, response, response.body) + }) + } + } + }) + + if (self.timeout && !self.timeoutTimer) { + self.timeoutTimer = setTimeout(function() { + self.req.abort() + var e = new Error("ETIMEDOUT") + e.code = "ETIMEDOUT" + self.emit("error", e) + }, self.timeout) + + // 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) + } + }); + } + + self.req.on('error', self.clientErrorHandler) + + self.emit('request', self.req) +} +Request.prototype.pipeDest = function (dest) { + var response = this.response + // Called after the response is received + if (dest.headers) { + dest.headers['content-type'] = response.headers['content-type'] + if (response.headers['content-length']) { + dest.headers['content-length'] = response.headers['content-length'] + } + } + if (dest.setHeader) { + for (var i in response.headers) { + dest.setHeader(i, response.headers[i]) + } + dest.statusCode = response.statusCode + } + if (this.pipefilter) this.pipefilter(response, dest) +} + +// Composable API +Request.prototype.setHeader = function (name, value, clobber) { + if (clobber === undefined) clobber = true + if (clobber || !this.headers.hasOwnProperty(name)) this.headers[name] = value + else this.headers[name] += ',' + value + return this +} +Request.prototype.setHeaders = function (headers) { + for (i in headers) {this.setHeader(i, headers[i])} + return this +} +Request.prototype.qs = function (q, clobber) { + var uri = { + protocol: this.uri.protocol, + host: this.uri.host, + pathname: this.uri.pathname, + query: clobber ? q : qs.parse(this.uri.query), + hash: this.uri.hash + }; + if (!clobber) for (var i in q) uri.query[i] = q[i] + + this.uri= url.parse(url.format(uri)) + + return this +} +Request.prototype.form = function (form) { + this.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8' + this.body = qs.stringify(form).toString('utf8') + return this +} +Request.prototype.multipart = function (multipart) { + var self = this + self.body = [] + + if (!self.headers['content-type']) { + self.headers['content-type'] = 'multipart/related;boundary="frontier"'; + } else { + self.headers['content-type'] = self.headers['content-type'].split(';')[0] + ';boundary="frontier"'; + } + + if (!multipart.forEach) throw new Error('Argument error, options.multipart.') + + multipart.forEach(function (part) { + var body = part.body + if(!body) throw Error('Body attribute missing in multipart.') + delete part.body + var preamble = '--frontier\r\n' + Object.keys(part).forEach(function(key){ + preamble += key + ': ' + part[key] + '\r\n' + }) + preamble += '\r\n' + self.body.push(new Buffer(preamble)) + self.body.push(new Buffer(body)) + self.body.push(new Buffer('\r\n')) + }) + self.body.push(new Buffer('--frontier--')) + return self +} +Request.prototype.json = function (val) { + this.setHeader('content-type', 'application/json') + this.setHeader('accept', 'application/json') + if (typeof val === 'boolean') { + if (typeof this.body === 'object') this.body = JSON.stringify(this.body) + } else { + this.body = JSON.stringify(val) + } + return this +} +Request.prototype.oauth = function (_oauth) { + var form + if (this.headers['content-type'] && + this.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) === + 'application/x-www-form-urlencoded' + ) { + form = qs.parse(this.body) + } + if (this.uri.query) { + form = qs.parse(this.uri.query) + } + if (!form) form = {} + var oa = {} + for (var i in form) oa[i] = form[i] + for (var i in _oauth) oa['oauth_'+i] = _oauth[i] + if (!oa.oauth_version) oa.oauth_version = '1.0' + if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( (new Date()).getTime() / 1000 ).toString() + if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '') + + oa.oauth_signature_method = 'HMAC-SHA1' + + var consumer_secret = oa.oauth_consumer_secret + delete oa.oauth_consumer_secret + var token_secret = oa.oauth_token_secret + delete oa.oauth_token_secret + + var baseurl = this.uri.protocol + '//' + this.uri.host + this.uri.pathname + var signature = oauth.hmacsign(this.method, baseurl, oa, consumer_secret, token_secret) + + // oa.oauth_signature = signature + for (var i in form) { + if ( i.slice(0, 'oauth_') in _oauth) { + // skip + } else { + delete oa['oauth_'+i] + } + } + this.headers.authorization = + 'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',') + this.headers.authorization += ',oauth_signature="'+oauth.rfc3986(signature)+'"' + return this +} +Request.prototype.jar = function (jar) { + var cookies + + if (this._redirectsFollowed === 0) { + this.originalCookieHeader = this.headers.cookie + } + + if (jar === false) { + // disable cookies + cookies = false; + this._disableCookies = true; + } else if (jar) { + // fetch cookie from the user defined cookie jar + cookies = jar.get({ url: this.uri.href }) + } else { + // fetch cookie from the global cookie jar + cookies = cookieJar.get({ url: this.uri.href }) + } + + if (cookies && cookies.length) { + var cookieString = cookies.map(function (c) { + return c.name + "=" + c.value + }).join("; ") + + if (this.originalCookieHeader) { + // Don't overwrite existing Cookie header + this.headers.cookie = this.originalCookieHeader + '; ' + cookieString + } else { + this.headers.cookie = cookieString + } + } + this._jar = jar + return this +} + + +// Stream API +Request.prototype.pipe = function (dest, opts) { if (this.response) { if (this._destdata) { throw new Error("You cannot pipe after data has been emitted from the response.") } else if (this._ended) { throw new Error("You cannot pipe after the response has been ended.") } else { - stream.Stream.prototype.pipe.call(this, dest) + stream.Stream.prototype.pipe.call(this, dest, opts) this.pipeDest(dest) return dest } } else { this.dests.push(dest) - stream.Stream.prototype.pipe.call(this, dest) + stream.Stream.prototype.pipe.call(this, dest, opts) return dest } } @@ -562,10 +662,11 @@ Request.prototype.write = function () { 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 () { +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.apply(this.req, arguments) + this.req.end() } Request.prototype.pause = function () { if (!this.response) throw new Error("This request has been piped before http.request() was called.") @@ -575,12 +676,36 @@ 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) } +Request.prototype.destroy = function () { + if (!this._ended) this.end() +} + +// organize params for post, put, head, del +function initParams(uri, options, callback) { + if ((typeof options === 'function') && !callback) callback = options; + if (typeof options === 'object') { + options.uri = uri; + } else if (typeof uri === 'string') { + options = {uri:uri}; + } else { + options = uri; + uri = options.uri; + } + return { uri: uri, options: options, callback: callback }; +} + +function request (uri, options, callback) { + if ((typeof options === 'function') && !callback) callback = options; + if (typeof options === 'object') { + options.uri = uri; + } else if (typeof uri === 'string') { + options = {uri:uri}; + } else { + options = uri; + } -function request (options, callback) { - if (typeof options === 'string') options = {uri:options} - if (callback) options.callback = callback + if (callback) options.callback = callback; var r = new Request(options) - r.request() return r } @@ -588,12 +713,12 @@ module.exports = request request.defaults = function (options) { var def = function (method) { - var d = function (opts, callback) { - if (typeof opts === 'string') opts = {uri:opts} + var d = function (uri, opts, callback) { + var params = initParams(uri, opts, callback); for (var i in options) { - if (opts[i] === undefined) opts[i] = options[i] + if (params.options[i] === undefined) params.options[i] = options[i] } - return method(opts, callback) + return method(params.uri, params.options, params.callback) } return d } @@ -620,33 +745,34 @@ request.forever = function (agentOptions, optionsArg) { } request.get = request -request.post = function (options, callback) { - if (typeof options === 'string') options = {uri:options} - options.method = 'POST' - return request(options, callback) -} -request.put = function (options, callback) { - if (typeof options === 'string') options = {uri:options} - options.method = 'PUT' - return request(options, callback) -} -request.head = function (options, callback) { - if (typeof options === 'string') options = {uri:options} - options.method = 'HEAD' +request.post = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'POST'; + return request(params.uri, params.options, params.callback) +} +request.put = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'PUT' + return request(params.uri, params.options, params.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) { throw new Error("HTTP HEAD requests MUST NOT include a request body.") } - return request(options, callback) + return request(params.uri, params.options, params.callback) } -request.del = function (options, callback) { - if (typeof options === 'string') options = {uri:options} - options.method = 'DELETE' - return request(options, callback) +request.del = function (uri, options, callback) { + var params = initParams(uri, options, callback); + params.options.method = 'DELETE' + return request(params.uri, params.options, params.callback) } request.jar = function () { return new CookieJar } request.cookie = function (str) { + if (str && str.uri) str = str.uri if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param") return new Cookie(str) } diff --git a/node_modules/request/mimetypes.js b/node_modules/request/mimetypes.js index 86910064c..59b21b419 100644 --- a/node_modules/request/mimetypes.js +++ b/node_modules/request/mimetypes.js @@ -1,5 +1,6 @@ // from http://github.com/felixge/node-paperboy exports.types = { + "3gp":"video/3gpp", "aiff":"audio/x-aiff", "arj":"application/x-arj-compressed", "asf":"video/x-ms-asf", @@ -50,17 +51,21 @@ exports.types = { "lzh":"application/octet-stream", "m":"text/plain", "m3u":"audio/x-mpegurl", + "m4v":"video/mp4", "man":"application/x-troff-man", "me":"application/x-troff-me", "midi":"audio/midi", "mif":"application/x-mif", "mime":"www/mime", + "mkv":" video/x-matrosk", "movie":"video/x-sgi-movie", - "mustache":"text/plain", "mp4":"video/mp4", + "mp41":"video/mp4", + "mp42":"video/mp4", "mpg":"video/mpeg", "mpga":"audio/mpeg", "ms":"application/x-troff-ms", + "mustache":"text/plain", "nc":"application/x-netcdf", "oda":"application/oda", "ogm":"application/ogg", @@ -123,6 +128,7 @@ exports.types = { "vrm":"x-world/x-vrml", "wav":"audio/x-wav", "wax":"audio/x-ms-wax", + "webm":"video/webm", "wma":"audio/x-ms-wma", "wmv":"video/x-ms-wmv", "wmx":"video/x-ms-wmx", @@ -134,7 +140,7 @@ exports.types = { "xpm":"image/x-xpixmap", "xwd":"image/x-xwindowdump", "xyz":"chemical/x-pdb", - "zip":"application/zip", + "zip":"application/zip" }; exports.lookup = function(ext, defaultType) { diff --git a/node_modules/request/oauth.js b/node_modules/request/oauth.js index 25db66977..31b9dc65f 100644 --- a/node_modules/request/oauth.js +++ b/node_modules/request/oauth.js @@ -19,7 +19,7 @@ function rfc3986 (str) { function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret, body) { // adapted from https://dev.twitter.com/docs/auth/oauth var base = - httpMethod + "&" + + (httpMethod || 'GET') + "&" + encodeURIComponent( base_uri ) + "&" + Object.keys(params).sort().map(function (i) { // big WTF here with the escape + encoding but it's what twitter wants diff --git a/node_modules/request/package.json b/node_modules/request/package.json index 7e194d583..305cf167b 100644 --- a/node_modules/request/package.json +++ b/node_modules/request/package.json @@ -1,7 +1,7 @@ { "name" : "request" , "description" : "Simplified HTTP request client." , "tags" : ["http", "simple", "util", "utility"] -, "version" : "2.9.100" +, "version" : "2.9.151" , "author" : "Mikeal Rogers <mikeal.rogers@gmail.com>" , "repository" : { "type" : "git" @@ -11,5 +11,5 @@ { "url" : "http://github.com/mikeal/request/issues" } , "engines" : ["node >= 0.3.6"] , "main" : "./main" -, "scripts": { "test": "bash tests/run.sh" } +, "scripts": { "test": "node tests/run.js" } } |