Skip to content
This repository
Browse code

Adding hawk signing to request.

  • Loading branch information...
commit cba36ce64e68bd26e230b65f81256776ac66e686 1 parent 3997f98
Mikeal Rogers authored March 01, 2013
1  README.md
Source Rendered
@@ -205,6 +205,7 @@ The first argument can be either a url or an options object. The only required o
205 205
 * `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request	
206 206
 * `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.
207 207
 * `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.
  208
+* `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.
208 209
 * `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.
209 210
 * `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)
210 211
 * `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)
19  main.js
@@ -21,6 +21,7 @@ var http = require('http')
21 21
   , qs = require('querystring')
22 22
   , crypto = require('crypto')
23 23
   , oauth = require('./oauth')
  24
+  , hawk = require('hawk')
24 25
   , uuid = require('./uuid')
25 26
   , ForeverAgent = require('./forever')
26 27
   , Cookie = require('./vendor/cookie')
@@ -113,6 +114,8 @@ util.inherits(Request, stream.Stream)
113 114
 Request.prototype.init = function (options) {
114 115
   var self = this
115 116
   
  117
+  self.method = options.method || 'GET'
  118
+  
116 119
   if (!options) options = {}
117 120
   if (request.debug) console.error('REQUEST', options)
118 121
   if (!self.pool && self.pool !== false) self.pool = globalPool
@@ -259,6 +262,7 @@ Request.prototype.init = function (options) {
259 262
   if (self.path.length === 0) self.path = '/'
260 263
 
261 264
 
  265
+  // Auth must happen last in case signing is dependent on other headers
262 266
   if (options.oauth) {
263 267
     self.oauth(options.oauth)
264 268
   }
@@ -266,6 +270,10 @@ Request.prototype.init = function (options) {
266 270
   if (options.aws) {
267 271
     self.aws(options.aws)
268 272
   }
  273
+  
  274
+  if (options.hawk) {
  275
+    self.hawk(options.hawk)
  276
+  }
269 277
 
270 278
   if (options.auth) {
271 279
     self.auth(
@@ -968,6 +976,17 @@ Request.prototype.aws = function (opts, now) {
968 976
   return this
969 977
 }
970 978
 
  979
+Request.prototype.hawk = function (opts) {
  980
+  var creds = {key:opts.key, id:opts.id, algorithm:opts.algorithm}
  981
+  delete opts.key
  982
+  delete opts.id
  983
+  delete opts.algorithm
  984
+  
  985
+  var port = this.uri.port || (this.uri.protocol === 'https:' ? 443 : 80)
  986
+  
  987
+  this.headers.Authorization = hawk.getAuthorizationHeader(creds, this.method, this.uri.path, this.uri.hostname, parseInt(port), opts)
  988
+}
  989
+
971 990
 Request.prototype.oauth = function (_oauth) {
972 991
   var form
973 992
   if (this.headers['content-type'] && 
43  package.json
... ...
@@ -1,16 +1,31 @@
1  
-{ "name" : "request"
2  
-, "description" : "Simplified HTTP request client."
3  
-, "tags" : ["http", "simple", "util", "utility"]
4  
-, "version" : "2.14.1"
5  
-, "author" : "Mikeal Rogers <mikeal.rogers@gmail.com>"
6  
-, "repository" :
7  
-  { "type" : "git"
8  
-  , "url" : "http://github.com/mikeal/request.git"
  1
+{
  2
+  "name": "request",
  3
+  "description": "Simplified HTTP request client.",
  4
+  "tags": [
  5
+    "http",
  6
+    "simple",
  7
+    "util",
  8
+    "utility"
  9
+  ],
  10
+  "version": "2.14.1",
  11
+  "author": "Mikeal Rogers <mikeal.rogers@gmail.com>",
  12
+  "repository": {
  13
+    "type": "git",
  14
+    "url": "http://github.com/mikeal/request.git"
  15
+  },
  16
+  "bugs": {
  17
+    "url": "http://github.com/mikeal/request/issues"
  18
+  },
  19
+  "engines": [
  20
+    "node >= 0.3.6"
  21
+  ],
  22
+  "main": "./main",
  23
+  "dependencies": {
  24
+    "form-data": "~0.0.3",
  25
+    "mime": "~1.2.7",
  26
+    "hawk": "~0.8.1"
  27
+  },
  28
+  "scripts": {
  29
+    "test": "node tests/run.js"
9 30
   }
10  
-, "bugs" :
11  
-  { "url" : "http://github.com/mikeal/request/issues" }
12  
-, "engines" : ["node >= 0.3.6"]
13  
-, "main" : "./main"
14  
-, "dependencies": { "form-data":"~0.0.3", "mime":"~1.2.7" }
15  
-, "scripts": { "test": "node tests/run.js" }
16 31
 }
33  tests/test-hawk.js
... ...
@@ -0,0 +1,33 @@
  1
+var createServer = require('http').createServer
  2
+  , request = require('../main')
  3
+  , hawk = require('hawk')
  4
+  , assert = require('assert')
  5
+  ;
  6
+
  7
+var server = createServer(function (req, resp) {
  8
+  
  9
+  var getCred = function (id, callback) {
  10
+    assert.equal(id, 'dh37fgj492je')
  11
+    var credentials = 
  12
+      { key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn'
  13
+      , algorithm: 'sha256'
  14
+      , user: 'Steve'
  15
+      }
  16
+    return callback(null, credentials)
  17
+  }
  18
+
  19
+  hawk.authenticate(req, getCred, {}, function (err, credentials, attributes) {
  20
+    resp.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' })
  21
+    resp.end(!err ? 'Hello ' + credentials.user : 'Shoosh!')
  22
+  })
  23
+  
  24
+})
  25
+
  26
+server.listen(8080, function () {
  27
+  var creds = {key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', algorithm: 'sha256', id:'dh37fgj492je'}
  28
+  request('http://localhost:8080', {hawk:creds}, function (e, r, b) {
  29
+    assert.equal(200, r.statusCode)
  30
+    assert.equal(b, 'Hello Steve')
  31
+    server.close()
  32
+  })
  33
+})

5 notes on commit cba36ce

sreuter

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

Mikeal Rogers
Owner

what is incompatible with 0.10?

Eran Hammer
Collaborator

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

Mikeal Rogers
Owner

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.
Something went wrong with that request. Please try again.