Skip to content

Commit

Permalink
Merge branch 'master' into travis-allowed-failures
Browse files Browse the repository at this point in the history
  • Loading branch information
nickmccurdy committed Mar 2, 2015
2 parents d7ed0a5 + a2c9ec7 commit f147e57
Show file tree
Hide file tree
Showing 22 changed files with 820 additions and 534 deletions.
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
language: node_js
node_js:
- "0.8"
- "0.10"
- "0.12"
- "io.js"
before_install: npm install -g npm@~1.4.6
after_script: ./node_modules/.bin/istanbul cover ./node_modules/tape/bin/tape tests/test-*.js --report lcovonly && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js --verbose
webhooks:
urls: https://webhooks.gitter.im/e/237280ed4796c19cc626
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
[![Coverage](https://img.shields.io/coveralls/request/request.svg?style=flat)](https://coveralls.io/r/request/request)
[![Gitter](https://img.shields.io/badge/gitter-join_chat-blue.svg?style=flat)](https://gitter.im/request/request?utm_source=badge)

## !!! Does not work with Node v0.12.x !!!

We're working on this. Want to help? See the
[contribution guidelines](https://github.com/request/request/blob/master/CONTRIBUTING.md),
help us fix the
[failing tests](https://travis-ci.org/request/request/jobs/49916823),
and [submit a PR](https://github.com/request/request/pulls)!

## Super simple to use

Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.
Expand Down Expand Up @@ -625,6 +633,7 @@ The first argument can be either a `url` or an `options` object. The only requir
tunneling proxy.
* `proxyHeaderExclusiveList` - A whitelist of headers to send
exclusively to a tunneling proxy and not to destination.
* `removeRefererHeader` - removes the referer header when a redirect happens (default: `false`).
The callback argument gets 3 arguments:
Expand Down
81 changes: 25 additions & 56 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,56 +47,23 @@ function request (uri, options, callback) {
options.callback = params.callback
options.uri = params.uri

return new request.Request(options)
}

function requester(params) {
if(typeof params.options._requester === 'function') {
return params.options._requester
}
return request
}

request.get = function (uri, options, callback) {
var params = initParams(uri, options, callback)
params.options.method = 'GET'
return requester(params)(params.uri || null, params.options, params.callback)
}

request.head = function (uri, options, callback) {
var params = initParams(uri, options, callback)
params.options.method = 'HEAD'

if (paramsHaveRequestBody(params)) {
if (params.options.method === 'HEAD' && paramsHaveRequestBody(params)) {
throw new Error('HTTP HEAD requests MUST NOT include a request body.')
}

return requester(params)(params.uri || null, params.options, params.callback)
}

request.post = function (uri, options, callback) {
var params = initParams(uri, options, callback)
params.options.method = 'POST'
return requester(params)(params.uri || null, params.options, params.callback)
return new request.Request(options)
}

request.put = function (uri, options, callback) {
var params = initParams(uri, options, callback)
params.options.method = 'PUT'
return requester(params)(params.uri || null, params.options, params.callback)
}
var verbs = ['get', 'head', 'post', 'put', 'patch', 'del']

request.patch = function (uri, options, callback) {
var params = initParams(uri, options, callback)
params.options.method = 'PATCH'
return requester(params)(params.uri || null, params.options, params.callback)
}

request.del = function (uri, options, callback) {
var params = initParams(uri, options, callback)
params.options.method = 'DELETE'
return requester(params)(params.uri || null, params.options, params.callback)
}
verbs.forEach(function(verb){
var method = verb === 'del' ? 'DELETE' : verb.toUpperCase()
request[verb] = function(uri, options, callback){
var params = initParams(uri, options, callback)
params.options.method = method
return this(params.uri || null, params.options, params.callback)
}
})

request.jar = function (store) {
return cookies.jar(store)
Expand All @@ -107,6 +74,12 @@ request.cookie = function (str) {
}

request.defaults = function (options, requester) {

if (typeof options === 'function') {
requester = options
options = {}
}

var self = this
var wrap = function (method) {
var headerlessOptions = function (options) {
Expand All @@ -131,25 +104,21 @@ request.defaults = function (options, requester) {
}

if (isFunction(requester)) {
if (method === self) {
method = requester
} else {
params.options._requester = requester
}
method = requester
}

return method(params.options, params.callback)
}
}

var defaults = wrap(self)
defaults.get = wrap(self.get)
defaults.patch = wrap(self.patch)
defaults.post = wrap(self.post)
defaults.put = wrap(self.put)
defaults.head = wrap(self.head)
defaults.del = wrap(self.del)
defaults.cookie = wrap(self.cookie)
defaults.get = self.get
defaults.patch = self.patch
defaults.post = self.post
defaults.put = self.put
defaults.head = self.head
defaults.del = self.del
defaults.cookie = self.cookie
defaults.jar = self.jar
defaults.defaults = self.defaults
return defaults
Expand Down
26 changes: 22 additions & 4 deletions lib/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ var md5 = helpers.md5
, toBase64 = helpers.toBase64


function Auth () {
function Auth (request) {
// define all public properties here
this.request = request
this.hasAuth = false
this.sentAuth = false
this.bearerToken = null
Expand Down Expand Up @@ -108,11 +109,28 @@ Auth.prototype.digest = function (method, path, authHeader) {
return authHeader
}

Auth.prototype.response = function (method, path, headers) {
Auth.prototype.onRequest = function (user, pass, sendImmediately, bearer) {
var self = this
, request = self.request

var authHeader
if (bearer !== undefined) {
authHeader = self.bearer(bearer, sendImmediately)
} else {
authHeader = self.basic(user, pass, sendImmediately)
}
if (authHeader) {
request.setHeader('authorization', authHeader)
}
}

Auth.prototype.onResponse = function (response) {
var self = this
, request = self.request

if (!self.hasAuth || self.sentAuth) { return null }

var c = caseless(headers)
var c = caseless(response.headers)

var authHeader = c.get('www-authenticate')
var authVerb = authHeader && authHeader.split(' ')[0].toLowerCase()
Expand All @@ -126,7 +144,7 @@ Auth.prototype.response = function (method, path, headers) {
return self.bearer(self.bearerToken, true)

case 'digest':
return self.digest(method, path, authHeader)
return self.digest(request.method, request.path, authHeader)
}
}

Expand Down
109 changes: 109 additions & 0 deletions lib/multipart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'use strict'

var uuid = require('node-uuid')
, CombinedStream = require('combined-stream')
, isstream = require('isstream')


function Multipart (request) {
this.request = request
this.boundary = uuid()
this.chunked = false
this.body = null
}

Multipart.prototype.isChunked = function (options) {
var self = this
, chunked = false
, parts = options.data || options

if (!parts.forEach) {
throw new Error('Argument error, options.multipart.')
}

if (options.chunked !== undefined) {
chunked = options.chunked
}

if (self.request.getHeader('transfer-encoding') === 'chunked') {
chunked = true
}

if (!chunked) {
parts.forEach(function (part) {
if(typeof part.body === 'undefined') {
throw new Error('Body attribute missing in multipart.')
}
if (isstream(part.body)) {
chunked = true
}
})
}

return chunked
}

Multipart.prototype.setHeaders = function (chunked) {
var self = this

if (chunked && !self.request.hasHeader('transfer-encoding')) {
self.request.setHeader('transfer-encoding', 'chunked')
}

var header = self.request.getHeader('content-type')

if (!header || header.indexOf('multipart') === -1) {
self.request.setHeader('content-type', 'multipart/related; boundary=' + self.boundary)
} else {
if (header.indexOf('boundary') !== -1) {
self.boundary = header.replace(/.*boundary=([^\s;])+.*/, '$1')
} else {
self.request.setHeader('content-type', header + '; boundary=' + self.boundary)
}
}
}

Multipart.prototype.build = function (parts, chunked) {
var self = this
var body = chunked ? new CombinedStream() : []

function add (part) {
return chunked ? body.append(part) : body.push(new Buffer(part))
}

if (self.request.preambleCRLF) {
add('\r\n')
}

parts.forEach(function (part) {
var preamble = '--' + self.boundary + '\r\n'
Object.keys(part).forEach(function (key) {
if (key === 'body') { return }
preamble += key + ': ' + part[key] + '\r\n'
})
preamble += '\r\n'
add(preamble)
add(part.body)
add('\r\n')
})
add('--' + self.boundary + '--')

if (self.request.postambleCRLF) {
add('\r\n')
}

return body
}

Multipart.prototype.onRequest = function (options) {
var self = this

var chunked = self.isChunked(options)
, parts = options.data || options

self.setHeaders(chunked)
self.chunked = chunked
self.body = self.build(parts, chunked)
}

exports.Multipart = Multipart
35 changes: 20 additions & 15 deletions lib/oauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ var querystring = require('querystring')
, oauth = require('oauth-sign')


exports.buildParams = function (_oauth, uri, method, query, form, qsLib) {
function OAuth (request) {
this.request = request
}

OAuth.prototype.buildParams = function (_oauth, uri, method, query, form, qsLib) {
var oa = {}
for (var i in _oauth) {
oa['oauth_' + i] = _oauth[i]
Expand Down Expand Up @@ -54,7 +58,7 @@ exports.buildParams = function (_oauth, uri, method, query, form, qsLib) {
return oa
}

exports.concatParams = function (oa, sep, wrap) {
OAuth.prototype.concatParams = function (oa, sep, wrap) {
wrap = wrap || ''

var params = Object.keys(oa).filter(function (i) {
Expand All @@ -71,13 +75,15 @@ exports.concatParams = function (oa, sep, wrap) {
}).join(sep)
}

exports.oauth = function (args) {
var uri = args.uri || {}
, method = args.method || ''
, headers = caseless(args.headers)
, body = args.body || ''
, _oauth = args.oauth || {}
, qsLib = args.qsLib || qs
OAuth.prototype.onRequest = function (_oauth) {
var self = this
, request = self.request

var uri = request.uri || {}
, method = request.method || ''
, headers = caseless(request.headers)
, body = request.body || ''
, qsLib = request.qsLib || qs

var form
, query
Expand All @@ -99,23 +105,22 @@ exports.oauth = function (args) {

var oa = this.buildParams(_oauth, uri, method, query, form, qsLib)

var data
switch (transport) {
case 'header':
data = 'OAuth ' + this.concatParams(oa, ',', '"')
request.setHeader('Authorization', 'OAuth ' + this.concatParams(oa, ',', '"'))
break

case 'query':
data = (query ? '&' : '?') + this.concatParams(oa, '&')
request.path = (query ? '&' : '?') + this.concatParams(oa, '&')
break

case 'body':
data = (form ? form + '&' : '') + this.concatParams(oa, '&')
request.body = (form ? form + '&' : '') + this.concatParams(oa, '&')
break

default:
throw new Error('oauth: transport_method invalid')
}

return {oauth:data, transport:transport}
}

exports.OAuth = OAuth

0 comments on commit f147e57

Please sign in to comment.