Skip to content

Commit

Permalink
Merge pull request #630 from walmartlabs/user/eran
Browse files Browse the repository at this point in the history
shot 0.1.0, Buffer response type, encoding
  • Loading branch information
geek committed Mar 4, 2013
2 parents ec66749 + 18953cc commit 9c99beb
Show file tree
Hide file tree
Showing 15 changed files with 250 additions and 192 deletions.
2 changes: 1 addition & 1 deletion examples/injection.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internals.main = function () {

server.inject(req, function (res) {

console.log(res.result || res.readPayload());
console.log(res.result);
});
};

Expand Down
25 changes: 25 additions & 0 deletions lib/response/buffer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Load modules

var Generic = require('./generic');
var Utils = require('../utils');


// Declare internals

var internals = {};


// Buffer response (Base -> Generic -> Buffer)

exports = module.exports = internals.Buffer = function (buffer) {

Generic.call(this);
this.variety = 'buffer';
this.varieties.buffer = true;

this._payload.push(buffer);

return this;
};

Utils.inherits(internals.Buffer, Generic);
139 changes: 70 additions & 69 deletions lib/response/generic.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var internals = {};

// Generic response (Base -> Generic)

exports = module.exports = internals.Generic = function () {
exports = module.exports = internals.Generic = function () {

Utils.assert(this.constructor !== internals.Generic, 'Generic must not be instantiated directly');

Expand All @@ -28,166 +28,167 @@ exports = module.exports = internals.Generic = function () {
this._payload = [];
this._headers = {};

return this;
return this;
};

Utils.inherits(internals.Generic, Base);


internals.Generic.prototype.getTtl = function () {
internals.Generic.prototype.getTtl = function () {

return this._code === 200 ? this._flags.ttl : 0;
return this._code === 200 ? this._flags.ttl : 0;
};


internals.Generic.prototype._prepare = function (request, callback) {
internals.Generic.prototype._prepare = function (request, callback) {

var self = this;

this._wasPrepared = true;
this._flags.encoding = this._flags.encoding || 'utf-8';

var length = 0;
this._payload.forEach(function (chunk) {
length += Buffer.byteLength(chunk);
this._payload.forEach(function (chunk) {

if (Buffer.isBuffer(chunk)) {
length += chunk.length;
}
else {
length += Buffer.byteLength(chunk, self._flags.encoding);
}
});

if (request.jsonp) {
if (request.jsonp) {
this.header('Content-Type', 'text/javascript');
length += request.jsonp.length + 3;

var payload = [request.jsonp, '('];
this._payload.forEach(function (chunk) {
payload.push(chunk.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029'));
this._payload.forEach(function (chunk) {

payload.push(Buffer.isBuffer(chunk) ? chunk : chunk.replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029'));
});
payload.push(');');
this._payload = payload;
this._payload = payload;
}

this.header('Content-Length', length);

if (this._flags.location) {
this._headers.Location = Headers.location(this._flags.location, request);
if (this._flags.location) {
this._headers.Location = Headers.location(this._flags.location, request);
}

Headers.cache(this, request);
Headers.cors(this, request);
Headers.state(this, request, function (err) {
Headers.content(this, request);
Headers.state(this, request, function (err) {

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

return callback(self);
});
return callback(self);
});
};


internals.Generic.prototype._transmit = function (request, callback) {
internals.Generic.prototype._transmit = function (request, callback) {

var self = this;

var prepare = function () {
var prepare = function () {

if (!self._payload.length ||
request.method === 'head') {
request.method === 'head') {

return send();
return send();
}

var availableEncodings = ['gzip', 'deflate', 'identity'];
var negotiator = new Negotiator(request.raw.req);
var encoding = negotiator.preferredEncoding(availableEncodings);

if (encoding === 'gzip') {
return prepareGzip();
}
if (encoding === 'deflate') {
return prepareDeflate();
if (['gzip', 'deflate'].indexOf(encoding) !== -1) {
return compress(encoding);
}

return send(self._payload);
return send(self._payload);
};

var prepareGzip = function () {
var compress = function (encoding) {

Async.map(self._payload, Zlib.gzip, function (err, results) {
var encoder = (encoding === 'gzip' ? Zlib.gzip : Zlib.deflate);
Async.map(self._payload, encoder, function (err, results) {

var length = 0;
results.forEach(function (result) {
results.forEach(function (result) {

length += result.length;
length += result.length;
});

self.header('Content-Encoding', 'gzip');
self.header('Content-Encoding', encoding);
self.header('Vary', 'Accept-Encoding');
self.header('Content-Length', length);

return send(results);
});
return send(results);
});
};

var prepareDeflate = function () {

Async.map(self._payload, Zlib.deflate, function (err, results) {
var send = function (payload) {

var length = 0;
results.forEach(function (result) {

length += result.length;
});

self.header('Content-Encoding', 'deflate');
self.header('Vary', 'Accept-Encoding');
self.header('Content-Length', length);
request.raw.res.once('error', function (err) {

return send(results);
});
};

var send = function (payload) {

request.raw.res.once('error', function (err) {

callback(err);
callback(err);
});

request.raw.res.writeHead(self._code, self._headers);

if (payload &&
payload.length) {
payload.length) {

payload.forEach(function (chunk) {
payload.forEach(function (chunk) {

request.raw.res.write(chunk);
});
if (Buffer.isBuffer(chunk)) {
request.raw.res.write(chunk);
}
else {
request.raw.res.write(chunk, self._flags.encoding);
}
});
}

request.raw.res.end();

callback();
callback();
};

prepare();
prepare();
};


internals.Generic.prototype.header = function (key, value) {
internals.Generic.prototype.header = function (key, value) {

this._headers[key] = value;
return this;
return this;
};


internals.Generic.prototype.type = function (type) {
internals.Generic.prototype.type = function (type) {

this._headers['Content-Type'] = type;
return this;
return this;
};


internals.Generic.prototype.created = function (uri) {
internals.Generic.prototype.created = function (uri) {

this._code = 201;
this._flags.location = uri;
return this;
return this;
};


internals.Generic.prototype.encoding = function (encoding) {

this._flags.encoding = encoding;
return this;
};
26 changes: 22 additions & 4 deletions lib/response/headers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ var State = require('../state');
var internals = {};


exports.location = function (uri, request) {

var isAbsolute = (uri.match(/^\w+\:\/\//));
return (isAbsolute ? uri : request.server.settings.uri + (uri.charAt(0) === '/' ? '' : '/') + uri);
};


exports.cache = function (response, request) {

var ttl = response.getTtl();
Expand Down Expand Up @@ -70,10 +77,21 @@ exports.cors = function (response, request) {
};


exports.location = function (uri, request) {

var isAbsolute = (uri.match(/^\w+\:\/\//));
return (isAbsolute ? uri : request.server.settings.uri + (uri.charAt(0) === '/' ? '' : '/') + uri);
exports.content = function (response, request) {

var type = response._headers['Content-Type'];
if (!type) {
return;
}

var hasParams = (type.indexOf(';') !== -1);
if (hasParams &&
type.match(/[; ]charset=/)) {

return;
}

response._headers['Content-Type'] = type + (hasParams ? ', ' : '; ') + 'charset=' + response._flags.encoding;
};


Expand Down
Loading

0 comments on commit 9c99beb

Please sign in to comment.