Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions lib/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,3 @@ exports.security = {
noOpen: true,
noSniff: true
};


// Views

exports.views = {
// defaultExtension: '',
// path: '',
// basePath: '',
compileOptions: {},
runtimeOptions: {},
layout: false,
layoutKeyword: 'content',
encoding: 'utf8',
isCached: true,
allowAbsolutePaths: false,
allowInsecureAccess: false,
// partialsPath: '',
contentType: 'text/html',
compileMode: 'sync'
};
2 changes: 1 addition & 1 deletion lib/directory.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ internals.generateListing = function (path, resource, selection, hasTrailingSlas

html += '</ul></body></html>';

return reply(new Response.Plain(html, request));
return reply(new Response.Message(html, request));
});
};

Expand Down
76 changes: 33 additions & 43 deletions lib/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ var Path = require('path');
var Crypto = require('crypto');
var Boom = require('boom');
var Hoek = require('hoek');
var Mimos = require('mimos');
var Response = require('./response');
var Schema = require('./schema');
var Mime = require('./mime');


// Declare internals
Expand All @@ -33,12 +33,12 @@ exports.handler = function (route, options) {

exports.load = function (path, request, options, callback) {

var response = new internals.Response(path, options, request);
return response._prepare(request, callback);
var response = exports.response(path, options, request);
return internals.prepare(response, callback);
};


exports.Response = internals.Response = function (path, options, request) {
exports.response = function (path, options, request) {

options = options || {};
Hoek.assert(!options.mode || ['attachment', 'inline'].indexOf(options.mode) !== -1, 'options.mode must be either false, attachment, or inline');
Expand All @@ -51,17 +51,13 @@ exports.Response = internals.Response = function (path, options, request) {
stat: null
};

Response.Plain.call(this, source, request, 'file');
return new Response.Message(source, request, { variety: 'file', marshall: internals.marshall, prepare: internals.prepare });
};

Hoek.inherits(internals.Response, Response.Plain);

internals.prepare = function (response, callback) {

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

var self = this;

var path = this.source.path;
var path = response.source.path;
Fs.stat(path, function (err, stat) {

if (err) {
Expand All @@ -72,82 +68,78 @@ internals.Response.prototype._prepare = function (request, callback) {
return callback(Boom.forbidden());
}

self.bytes(stat.size);
response.bytes(stat.size);

if (!self.headers['content-type']) {
self.type(Mime.path(path).type || 'application/octet-stream');
if (!response.headers['content-type']) {
response.type(Mimos.path(path).type || 'application/octet-stream');
}

self._header('last-modified', stat.mtime.toUTCString());
response._header('last-modified', stat.mtime.toUTCString());

if (request.server._etags) {
if (response.request.server._etags) {

// Use stat info for an LRU cache key.

var cachekey = [path, stat.ino, stat.size, stat.mtime.getTime()].join('-');

// The etag must hash the file contents in order to be consistent across distributed deployments

var cachedEtag = request.server._etags.get(cachekey);
var cachedEtag = response.request.server._etags.get(cachekey);
if (cachedEtag) {
self.etag(cachedEtag, { vary: true });
response.etag(cachedEtag, { vary: true });
}
else {
var hash = Crypto.createHash('sha1');
self.on('peek', function (chunk) {
response.on('peek', function (chunk) {

hash.update(chunk);
});

self.once('finish', function () {
response.once('finish', function () {

var etag = hash.digest('hex');
request.server._etags.set(cachekey, etag);
response.request.server._etags.set(cachekey, etag);
});
}
}

if (self.source.settings.mode) {
var fileName = self.source.settings.filename || Path.basename(path);
self._header('content-disposition', self.source.settings.mode + '; filename=' + encodeURIComponent(fileName));
if (response.source.settings.mode) {
var fileName = response.source.settings.filename || Path.basename(path);
response._header('content-disposition', response.source.settings.mode + '; filename=' + encodeURIComponent(fileName));
}

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


internals.Response.prototype._marshall = function (request, callback) {

var self = this;
internals.marshall = function (response, callback) {

if (!this.source.settings.lookupCompressed ||
request.info.acceptEncoding !== 'gzip') {
if (!response.source.settings.lookupCompressed ||
response.request.info.acceptEncoding !== 'gzip') {

return this._openStream(this.source.path, callback);
return internals.openStream(response, response.source.path, callback);
}

var gzFile = this.source.path + '.gz';
var gzFile = response.source.path + '.gz';
Fs.stat(gzFile, function (err, stat) {

if (err ||
stat.isDirectory()) {

return self._openStream(self.source.path, callback);
return internals.openStream(response, response.source.path, callback);
}

self.bytes(stat.size);
self._header('content-encoding', 'gzip');
self.vary('accept-encoding');
response.bytes(stat.size);
response._header('content-encoding', 'gzip');
response.vary('accept-encoding');

return self._openStream(gzFile, callback);
return internals.openStream(response, gzFile, callback);
});
};


internals.Response.prototype._openStream = function (path, callback) {

var self = this;
internals.openStream = function (response, path, callback) {

var fileStream = Fs.createReadStream(path);

Expand All @@ -160,9 +152,7 @@ internals.Response.prototype._openStream = function (path, callback) {
var onOpen = function () {

fileStream.removeListener('error', onError);

self._payload = fileStream;
return callback();
return callback(null, fileStream);
};

fileStream.once('error', onError);
Expand Down
12 changes: 6 additions & 6 deletions lib/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
var H2o2 = require('h2o2');
var Hoek = require('hoek');
var Items = require('items');
var Vision = require('vision');
var Response = require('./response');
var File = require('./file');
var Directory = require('./directory');
var Views = require('./views');
var Methods = require('./methods');


Expand Down Expand Up @@ -111,13 +111,13 @@ exports.replyInterface = function (request, finalize, base) {
if (viewsManager) {
reply.view = function (template, context, options) {

return internals.wrap(new Views.Response(viewsManager, template, context, options, request), request, finalize);
return internals.wrap(viewsManager.response(template, context, options, request, Response.Message), request, finalize);
};
}

reply.file = function (path, options) {

return internals.wrap(new File.Response(path, options, request), request, finalize);
return internals.wrap(File.response(path, options, request), request, finalize);
};

reply.proxy = function (options) {
Expand Down Expand Up @@ -161,8 +161,8 @@ internals.wrap = function (result, request, finalize) {

var prepare = function () {

if (response._prepare) {
return response._prepare(request, finalize);
if (response._processors.prepare) {
return response._processors.prepare(response, finalize);
}

return finalize(response);
Expand Down Expand Up @@ -238,7 +238,7 @@ exports.register = function (pack) {
pack._handler('proxy', H2o2.handler);
pack._handler('file', File.handler);
pack._handler('directory', Directory.handler);
pack._handler('view', Views.handler);
pack._handler('view', Vision.handler);
};


Expand Down
65 changes: 0 additions & 65 deletions lib/mime.js

This file was deleted.

19 changes: 13 additions & 6 deletions lib/pack.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
// Load modules

var Path = require('path');
var Events = require('events');
var Path = require('path');
var Catbox = require('catbox');
var CatboxMemory = require('catbox-memory');
var Hoek = require('hoek');
var Items = require('items');
var Kilt = require('kilt');
var Server = require('./server');
var Views = require('./views');
var Vision = require('vision');
var Defaults = require('./defaults');
var Ext = require('./ext');
var Methods = require('./methods');
var Handler = require('./handler');
var Methods = require('./methods');
var Response = require('./response');
var Schema = require('./schema');
var Server = require('./server');
var Utils = require('./utils');


Expand Down Expand Up @@ -397,9 +398,15 @@ internals.Pack.prototype._plugin = function (plugin, registerOptions, state, cal

root.views = function (options) {

Hoek.assert(options, 'Missing views options');
Hoek.assert(!env.views, 'Cannot set plugin views manager more than once');
var override = (!options.basePath && env.path ? { basePath: env.path } : null);
env.views = new Views.Manager(options, override);

if (!options.basePath && env.path) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be defensive against a null/undefined options?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an old issue. There wasn't one before. But I'll add it.

options = Utils.shallow(options);
options.basePath = env.path;
}

env.views = new Vision.Manager(options, Response);
};

root.render = function (template, context /*, options, callback */) {
Expand Down
6 changes: 6 additions & 0 deletions lib/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,12 @@ internals.Request.prototype._tap = function () {
};


internals.Request.prototype.generateResponse = function (source, options) {

return new Response.Message(source, this, options);
};


internals.Peek = function (response) {

Stream.Transform.call(this);
Expand Down
Loading