Permalink
Browse files

Adding hawk signing to request.

  • Loading branch information...
1 parent 3997f98 commit cba36ce64e68bd26e230b65f81256776ac66e686 @mikeal mikeal committed Mar 1, 2013
Showing with 82 additions and 14 deletions.
  1. +1 โˆ’0 README.md
  2. +19 โˆ’0 main.js
  3. +29 โˆ’14 package.json
  4. +33 โˆ’0 tests/test-hawk.js
View
@@ -205,6 +205,7 @@ The first argument can be either a url or an options object. The only required o
* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request
* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.
* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.
+* `hawk` - Options for [Hawk signing](https://github.com/hueniverse/hawk). The `id`, `key`, and `algorithm` properties are used for credentials, any other properties will be treated as extensions.
* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.
* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)
* `aws` - object containing aws signing information, should have the properties `key` and `secret` as well as `bucket` unless you're specifying your bucket as part of the path, or you are making a request that doesn't use a bucket (i.e. GET Services)
View
@@ -21,6 +21,7 @@ var http = require('http')
, qs = require('querystring')
, crypto = require('crypto')
, oauth = require('./oauth')
+ , hawk = require('hawk')
, uuid = require('./uuid')
, ForeverAgent = require('./forever')
, Cookie = require('./vendor/cookie')
@@ -113,6 +114,8 @@ util.inherits(Request, stream.Stream)
Request.prototype.init = function (options) {
var self = this
+ self.method = options.method || 'GET'
+
if (!options) options = {}
if (request.debug) console.error('REQUEST', options)
if (!self.pool && self.pool !== false) self.pool = globalPool
@@ -259,13 +262,18 @@ Request.prototype.init = function (options) {
if (self.path.length === 0) self.path = '/'
+ // Auth must happen last in case signing is dependent on other headers
if (options.oauth) {
self.oauth(options.oauth)
}
if (options.aws) {
self.aws(options.aws)
}
+
+ if (options.hawk) {
+ self.hawk(options.hawk)
+ }
if (options.auth) {
self.auth(
@@ -968,6 +976,17 @@ Request.prototype.aws = function (opts, now) {
return this
}
+Request.prototype.hawk = function (opts) {
+ var creds = {key:opts.key, id:opts.id, algorithm:opts.algorithm}
+ delete opts.key
+ delete opts.id
+ delete opts.algorithm
+
+ var port = this.uri.port || (this.uri.protocol === 'https:' ? 443 : 80)
+
+ this.headers.Authorization = hawk.getAuthorizationHeader(creds, this.method, this.uri.path, this.uri.hostname, parseInt(port), opts)
+}
+
Request.prototype.oauth = function (_oauth) {
var form
if (this.headers['content-type'] &&
View
@@ -1,16 +1,31 @@
-{ "name" : "request"
-, "description" : "Simplified HTTP request client."
-, "tags" : ["http", "simple", "util", "utility"]
-, "version" : "2.14.1"
-, "author" : "Mikeal Rogers <mikeal.rogers@gmail.com>"
-, "repository" :
- { "type" : "git"
- , "url" : "http://github.com/mikeal/request.git"
+{
+ "name": "request",
+ "description": "Simplified HTTP request client.",
+ "tags": [
+ "http",
+ "simple",
+ "util",
+ "utility"
+ ],
+ "version": "2.14.1",
+ "author": "Mikeal Rogers <mikeal.rogers@gmail.com>",
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/mikeal/request.git"
+ },
+ "bugs": {
+ "url": "http://github.com/mikeal/request/issues"
+ },
+ "engines": [
+ "node >= 0.3.6"
+ ],
+ "main": "./main",
+ "dependencies": {
+ "form-data": "~0.0.3",
+ "mime": "~1.2.7",
+ "hawk": "~0.8.1"
+ },
+ "scripts": {
+ "test": "node tests/run.js"
}
-, "bugs" :
- { "url" : "http://github.com/mikeal/request/issues" }
-, "engines" : ["node >= 0.3.6"]
-, "main" : "./main"
-, "dependencies": { "form-data":"~0.0.3", "mime":"~1.2.7" }
-, "scripts": { "test": "node tests/run.js" }
}
View
@@ -0,0 +1,33 @@
+var createServer = require('http').createServer
+ , request = require('../main')
+ , hawk = require('hawk')
+ , assert = require('assert')
+ ;
+
+var server = createServer(function (req, resp) {
+
+ var getCred = function (id, callback) {
+ assert.equal(id, 'dh37fgj492je')
+ var credentials =
+ { key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn'
+ , algorithm: 'sha256'
+ , user: 'Steve'
+ }
+ return callback(null, credentials)
+ }
+
+ hawk.authenticate(req, getCred, {}, function (err, credentials, attributes) {
+ resp.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' })
+ resp.end(!err ? 'Hello ' + credentials.user : 'Shoosh!')
+ })
+
+})
+
+server.listen(8080, function () {
+ var creds = {key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', algorithm: 'sha256', id:'dh37fgj492je'}
+ request('http://localhost:8080', {hawk:creds}, function (e, r, b) {
+ assert.equal(200, r.statusCode)
+ assert.equal(b, 'Hello Steve')
+ server.close()
+ })
+})

5 comments on commit cba36ce

@sreuter

@mikeal @hueniverse The integration of hawk leaves request compatible with node 0.8.x only :-(

@mikeal
Member
mikeal commented on cba36ce Mar 15, 2013

what is incompatible with 0.10?

@hueniverse

All the hawk tests pass under node 0.10. Can you provide more info?

@mikeal
Member
mikeal commented on cba36ce Mar 15, 2013

did you mean that it only works on 0.8.0+? cause that's intentional, request only supports the latest two stable releases of node.js.

@sreuter

@mikeal: current package.json of request states otherwise:

  "engines": [
    "node >= 0.3.6"
  ],

@hueniverse: hawk package.json states it only runs on 0.8.x:

 "engines": {
    "node": "0.8.x"
  },
Please sign in to comment.