Skip to content

Commit

Permalink
Merge pull request hapijs#736 from spumko/v0.17
Browse files Browse the repository at this point in the history
Node v0.10
  • Loading branch information
Eran Hammer committed Apr 5, 2013
2 parents a71b3e0 + e9d6195 commit dde10fa
Show file tree
Hide file tree
Showing 25 changed files with 437 additions and 551 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
language: node_js

node_js:
- 0.8
- 0.10

notifications:
irc:
channels:
- "irc.freenode.net#hapi"
skip_join: true
skip_join: true
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ with everything else.

For the latest updates and release information follow [@hapijs](https://twitter.com/hapijs) on twitter.

Current version: **0.16.0**
Current version: **0.17.0**
Node version: **0.10** required

[![Build Status](https://secure.travis-ci.org/spumko/hapi.png)](http://travis-ci.org/spumko/hapi)
<img src="https://raw.github.com/olivierlacan/shields/master/coveralls/coveralls_100.png" />
Expand Down
6 changes: 3 additions & 3 deletions docs/Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -638,8 +638,8 @@ to write additional text as the configuration itself serves as a living document
- `response` - validation rules for outgoing responses' payload (response body). Defaults to no validation (any payload allowed). Set to an empty object _'{}'_ to forbid payloads. See [Response Validation](#response-validation) for more information.
- `payload` - determines how the request payload is processed. Defaults to _'parse'_ if `schema` is present or `method` is _'POST'_ or _'PUT'_, otherwise _'stream'_. Payload processing is configured using the server [`payload`](#payload) option. Options are:
- _'stream'_ - the incoming request stream is left untouched, leaving it up to the handler to process the request via _'request.raw.req'_. Note that the request readable stream is put in a paused state and must be resumed before it will emit data events.
- _'raw'_ - the payload is read and stored in _'request.rawBody'_ but not parsed.
- _'parse'_ - the payload is read and stored in _'request.rawBody'_ and then parsed (JSON or form-encoded) and stored in _'request.payload'_.
- _'raw'_ - the payload is read and stored in _'request.rawPayload'_ as a Buufer and is not parsed.
- _'parse'_ - the payload is read and stored in _'request.rawPayload'_ as a Buffer, and then parsed (JSON or form-encoded) and stored in _'request.payload'_.
- `cache` - if the the route method is 'GET', the route can be configured to use the cache as described in [Caching](#caching).
- `pre` - an array with pre-handler methods as described in [Route Prerequisites](#prerequisites).
- `auth` - authentication configuration
Expand Down Expand Up @@ -830,7 +830,7 @@ When the provided route handler method is called, it receives a _request_ object
- _'method'_ - the request method as a _lowercase_ string. (Examples: `'get'`, `'post'`).
- _'query'_ - an object containing the query parameters.
- _'params'_ - an object containing the path named parameters as described in [Path Parameters](#parameters).
- _'rawBody'_ - the raw request payload (except for requests with `config.payload` set to _'stream'_).
- _'rawPayload'_ - the raw request payload Buffer (except for requests with `config.payload` set to _'stream'_).
- _'payload'_ - an object containing the parsed request payload (for requests with `config.payload` set to _'parse'_).
- _'state'_ - an object containing parsed HTTP state information (cookies).
- _'session'_ - available for authenticated requests and includes:
Expand Down
45 changes: 14 additions & 31 deletions lib/auth/hawk.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ internals.Scheme.prototype.authenticate = function (request, callback) {

internals.Scheme.prototype.authenticatePayload = function (request, callback) {

var isValid = Hawk.server.authenticatePayload(request.rawBody, request.auth.credentials, request.auth.artifacts, request.raw.req.headers['content-type']);
var isValid = Hawk.server.authenticatePayload(request.rawPayload, request.auth.credentials, request.auth.artifacts, request.raw.req.headers['content-type']);

return callback(isValid ? null : Boom.unauthorized('Payload is invalid'));
};
Expand All @@ -50,41 +50,24 @@ internals.Scheme.prototype.responseHeader = function (request, response, callbac
contentType: response._headers['Content-Type']
};

if (response._payload &&
response._payload.length) {
response.header('Trailer', 'Server-Authorization');
response.header('Transfer-Encoding', 'chunked');

options.payload = response._payload.join('');
var payload = '';
response.peek.on('preview', function (chunk) {

var header = Hawk.server.header(request.auth.credentials, request.auth.artifacts, options);
if (!header) {
return callback(Boom.internal('Failed generating Hawk response authorization header'));
}

response.header('Server-Authorization', header);
return callback();
}

if (response.variety === 'stream') {

response.header('Trailer', 'Server-Authorization');

var payload = '';
response.stream.on('data', function (chunk) {

payload += chunk;
});
payload += chunk;
});

response.stream.once('end', function (chunk) {
response.peek.on('finish', function () {

payload += chunk;
options.payload = payload;
options.payload = payload;

var header = Hawk.server.header(request.auth.credentials, request.auth.artifacts, options);
if (header) {
request.raw.res.addTrailers({ 'Server-Authorization': header });
}
});
}
var header = Hawk.server.header(request.auth.credentials, request.auth.artifacts, options);
if (header) {
request.raw.res.addTrailers({ 'Server-Authorization': header });
}
});

callback();
};
Expand Down
3 changes: 1 addition & 2 deletions lib/ext.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,11 @@ internals.Ext.runProtected = function (log, tags, callback, setup) {

domain.on('error', function (err) {

domain.dispose();
log(['uncaught'].concat(tags || []), err); // 'uncaught' treated special in request._log
return finish(Boom.internal('Uncaught error', err));
});

// Execute functon
// Execute function

domain.enter();
run();
Expand Down
4 changes: 1 addition & 3 deletions lib/pack.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,9 +408,7 @@ internals.getSourceFilePath = function () {

for (var i = 0, il = stack.length; i < il; ++i) {
var stackLine = stack[i];
if (stackLine[3] === 'internals.Pack.require' ||
stackLine[3] === 'internals.Pack.allow.scoped.require') { // The file that calls require is next

if (stackLine[3].lastIndexOf('.require') === stackLine[3].length - 8) { // The file that calls require is next
callerFile = stack[i + 1][0];
break;
}
Expand Down
77 changes: 41 additions & 36 deletions lib/payload.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ internals.validGzip = new Buffer(['0x1f', '0x8b']);

exports.read = function (request, next) {

var req = request.raw.req;

if (request.method === 'get' ||
request.method === 'head') {

Expand All @@ -35,6 +33,7 @@ exports.read = function (request, next) {

// Check content size

var req = request.raw.req;
var contentLength = req.headers['content-length'];
if (contentLength &&
parseInt(contentLength, 10) > request.server.settings.payload.maxBytes) {
Expand Down Expand Up @@ -67,10 +66,6 @@ exports.read = function (request, next) {

// Read incoming body

var isGZip = (req.headers['content-encoding'] === 'gzip');
var encoding = isGZip ? 'base64' : 'utf8';
req.setEncoding(encoding);

req.on('close', function () {

return finish(Boom.internal('Request closed before finished reading'));
Expand All @@ -81,71 +76,81 @@ exports.read = function (request, next) {
return finish(Boom.internal('Request error before finished reading: ' + err));
});

var payload = '';
req.on('data', function (chunk) {
var buffers = [];
var buffersLength = 0

req.on('readable', function () {

if (payload.length + chunk.length > request.server.settings.payload.maxBytes) {
var chunk = req.read();
if (!chunk) {
return;
}

if (buffersLength + chunk.length > request.server.settings.payload.maxBytes) {
return finish(Boom.badRequest('Payload size greater than maximum allowed: ' + request.server.settings.payload.maxBytes));
}

payload += chunk.toString(encoding);
buffers.push(chunk);
buffersLength += chunk.length;
});

req.on('end', function () {

if (isBailed) {
return; // next() already called
}

var unzip = function () {
var review = function () {

var payloadBuf = new Buffer(payload, encoding);
if (!internals.isDeflate(payloadBuf) && !internals.isGzip(payloadBuf)) {
return finish(Boom.badRequest('Invalid compressed payload'));
if (isBailed) {
return; // next() already called
}

Zlib.unzip(payloadBuf, function (err, buffer) { // Err shouldn't exist since the buffer is validated above
var payload = Buffer.concat(buffers, buffersLength);

var unzipped = buffer.toString();
request.rawBody = unzipped;
return parse(unzipped);
});
if (payload.length &&
(req.headers['content-encoding'] === 'gzip' || req.headers['content-encoding'] === 'deflate')) {

if (!internals.isDeflate(payload) && !internals.isGzip(payload)) {
return finish(Boom.badRequest('Invalid compressed payload'));
}

Zlib.unzip(payload, function (err, unzipped) { // Err shouldn't exist since the buffer is validated above

return parse(unzipped);
});

return;
}

parse(payload);
};

var parse = function (result) {
var parse = function (payload) {

request.rawPayload = (payload.length ? payload : null);

if (level !== 'parse') { // 'raw'
if (level !== 'parse') { // 'raw'
return finish();
}

request.payload = {};

if (!result) {
if (!payload.length) {
return finish();
}

// Set parser

internals.parse(result, req.headers, function (err, payload) {
internals.parse(payload.toString('utf8'), req.headers, function (err, result) {

if (err) {
return finish(err);
}

request.payload = payload;
request.payload = result;
return finish();
});
};

if (isGZip) {
return unzip();
}

request.rawBody = payload;
parse(payload);
review();
});

req.resume();
};


Expand Down
5 changes: 2 additions & 3 deletions lib/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ internals.Proxy.prototype.handler = function () {
// Stream interface

if (!isGet &&
request.rawBody) {
request.rawPayload) {

options.headers['Content-Type'] = req.headers['content-type'];
options.body = request.rawBody;
options.body = request.rawPayload;
}

var reqStream = self.httpClient(options);
Expand All @@ -108,7 +108,6 @@ internals.Proxy.prototype.handler = function () {
request.route.payload === 'stream') {

request.raw.req.pipe(reqStream);
request.raw.req.resume();
}
}
});
Expand Down
6 changes: 1 addition & 5 deletions lib/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ exports = module.exports = internals.Request = function (server, req, res, optio

options = options || {};

// Pause request

req.pause(); // Must be done before switching event execution context

// Public members

this.server = server;
Expand Down Expand Up @@ -72,7 +68,7 @@ exports = module.exports = internals.Request = function (server, req, res, optio

// query
// params
// rawBody
// rawPayload
// payload

// state
Expand Down
21 changes: 20 additions & 1 deletion lib/response/base.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Load modules

var Stream = require('stream');
var Utils = require('../utils');


Expand All @@ -20,6 +21,8 @@ exports = module.exports = internals.Base = function () {
this._states = {}; // Not cached
this._wasPrepared = false;

this.peek = new internals.Peek();

return this;
};

Expand Down Expand Up @@ -78,4 +81,20 @@ this._transmit = function (request, callback) {
callback();
};
*/
*/


internals.Peek = function () {

Stream.Writable.call(this);
return this;
};

Utils.inherits(internals.Peek, Stream.Writable);


internals.Peek.prototype._write = function (chunk, encoding, callback) {

this.emit('preview', chunk, encoding);
callback();
};
Loading

0 comments on commit dde10fa

Please sign in to comment.