diff --git a/README.md b/README.md
index 8d001ea43..6ea7ce761 100755
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@ with everything else.
For the latest updates and release information follow [@hapijs](https://twitter.com/hapijs) on twitter.
-Current version: **0.14.3**
+Current version: **0.15.0**
[![Build Status](https://secure.travis-ci.org/walmartlabs/hapi.png)](http://travis-ci.org/walmartlabs/hapi)
@@ -97,20 +97,20 @@ The **hapi** route handler can be used to easily serve files, directories, rende
```javascript
server.route({
method: 'GET',
- path: '/{path*}',
- handler: {
- directory: { path: './public', listing: false, index: true }
- }
+ path: '/{path*}',
+ handler: {
+ directory: { path: './public', listing: false, index: true }
+ }
});
```
Create a folder named _'public'_ and add a _'index.html'_ file in the folder with the following contents:
```html
-
Hello Static
-
- Hello Static
-
+ Hello Static
+
+ Hello Static
+
```
@@ -127,10 +127,10 @@ npm install handlebars
Next create a directory named _'templates'_ that will contain the template files. In this directory create a _'index.html'_ with the following contents:
```html
- {{greeting}}
-
- {{greeting}}
-
+ {{greeting}}
+
+ {{greeting}}
+
```
@@ -154,7 +154,7 @@ var server = new Hapi.Server('localhost', 8000, options);
var hello = {
handler: function (request) {
- // Render the view with the custom greeting
+ // Render the view with the custom greeting
request.reply.view('index.html', { greeting: 'hello world' }).send();
}
};
diff --git a/docs/Reference.md b/docs/Reference.md
index ae0053ace..18692b70a 100755
--- a/docs/Reference.md
+++ b/docs/Reference.md
@@ -178,7 +178,7 @@ function onRequest(request, next) {
**hapi** provides built-in support for serving static files and directories as described in [File](#file) and [Directory](#directory).
When these handlers are provided with relative paths, the `files.relativeTo` server option determines how these paths are resolved
-and defaults to _'routes'_:
+and defaults to _'process'_:
- _'routes'_ - relative paths are resolved based on the location of the files in which the server's _'route()'_ method is called. This means the location of the source code determines the location of the static resources when using relative paths.
- _'process'_ - relative paths are resolved using the active process path (_'process.cwd()'_).
@@ -799,7 +799,7 @@ It is possible with hapi to setup a reverse proxy for routes. This is especiall
- `host` - The host to proxy requests to. The same path on the client request will be used as the path to the host.
- `port` - The port to use when making a request to the host.
- `protocol` - The protocol to use when making a request to the proxied host (http or https)
-- `mapUri` - A function that receives the clients request and a passes the URI to a callback to make the proxied request to. If host is set mapUri cannot be used, set either host or mapUri.
+- `mapUri` - A function used to map the request URI to the proxied URI. The function signature is _function (request, callback)_ where 'request' is the incoming request object, and callback is 'function (err, uri)'. Cannot be used together with `host`, `port`, or `protocol`.
- `postResponse` - A function that will be executed before sending the response to the client for requests that can be cached. Use this for any custom error handling of responses from the proxied endpoint.
- `httpClient` - A function that should make the request to the remote server and use execute the callback with a response. By default this uses _'request'_ as the module. The signature is (options, callback) where options will contain a url and method.
@@ -814,6 +814,16 @@ http.route({ method: 'GET', path: '/', handler: { proxy: { protocol: 'http', hos
http.start();
```
+Using `mapUri`:
+```javascript
+var mapper = function (request, callback) {
+
+ callback(null, 'https://www.google.com/?q=' + request.param.term);
+};
+
+http.route({ method: 'GET', path: '/{term}', handler: { proxy: { mapUri: mapper } } });
+```
+
#### File
diff --git a/lib/defaults.js b/lib/defaults.js
index f6b238195..8df429391 100755
--- a/lib/defaults.js
+++ b/lib/defaults.js
@@ -47,7 +47,7 @@ exports.server = {
// Files path
files: {
- relativeTo: 'routes' // Determines what file and directory handlers use to base relative paths off: 'routes', 'process'
+ relativeTo: 'process' // Determines what file and directory handlers use to base relative paths off: 'routes', 'process'
},
// timeout limits
diff --git a/lib/files.js b/lib/files.js
index c034ba5ef..511a61947 100755
--- a/lib/files.js
+++ b/lib/files.js
@@ -10,7 +10,7 @@ var Response = require('./response');
var internals = {};
-exports.fileHandler = function (route, filePath) {
+exports.fileHandler = function (route, filePath) {
Utils.assert(filePath && (typeof filePath === 'function' || typeof filePath === 'string'), 'Invalid file path');
Utils.assert(typeof filePath !== 'string' || route.params.length === 0, 'Route path with static file path cannot contain a parameter');
@@ -20,38 +20,38 @@ exports.fileHandler = function (route, filePath) {
// Normalize static string path
- if (typeof filePath === 'string') {
+ if (typeof filePath === 'string') {
var staticPath = filePath;
- if (staticPath[0] !== '/') {
- staticPath = absolutePath + '/' + staticPath;
- }
+ if (staticPath[0] !== '/') {
+ staticPath = absolutePath + '/' + staticPath;
+ }
}
- var handler = function (request) {
+ var handler = function (request) {
var path = null;
- if (typeof filePath === 'function') {
+ if (typeof filePath === 'function') {
path = filePath(request);
// Normalize function string path
- if (path[0] !== '/') {
- path = absolutePath + '/' + path;
- }
+ if (path[0] !== '/') {
+ path = absolutePath + '/' + path;
+ }
}
- else {
- path = staticPath;
+ else {
+ path = staticPath;
}
- return request.reply(new Response.File(path));
+ return request.reply(new Response.File(path));
}
- return handler;
+ return handler;
};
-exports.directoryHandler = function (route, options) {
+exports.directoryHandler = function (route, options) {
Utils.assert(options, 'Options must exist');
Utils.assert(typeof options === 'object' && options.path, 'Options must be an object with a path');
@@ -64,8 +64,8 @@ exports.directoryHandler = function (route, options) {
// Normalize static string path
- if (typeof settings.path === 'string') {
- settings.path = [settings.path];
+ if (typeof settings.path === 'string') {
+ settings.path = [settings.path];
}
var normalize = function (path) {
@@ -90,71 +90,79 @@ exports.directoryHandler = function (route, options) {
});
}
- var handler = function (request) {
+ var handler = function (request) {
var paths = normalized;
- if (typeof settings.path === 'function') {
- paths = [normalize(settings.path(request))];
+ if (typeof settings.path === 'function') {
+ paths = [normalize(settings.path(request))];
}
// Append parameter
var selection = null;
- if (request._paramsArray[0]) {
- if (request._paramsArray[0].indexOf('..') !== -1) {
- return request.reply(Boom.forbidden());
+ if (request._paramsArray[0]) {
+ if (request._paramsArray[0].indexOf('..') !== -1) {
+ return request.reply(Boom.forbidden());
}
- selection = request._paramsArray[0];
+ selection = request._paramsArray[0];
}
// Generate response
- var response = new Response.Directory(paths, {
-
+ var response = new Response.Directory(paths, {
+
resource: request.path,
selection: selection,
index: settings.index,
listing: settings.listing,
- showHidden: settings.showHidden
+ showHidden: settings.showHidden
});
- return request.reply(response);
+ return request.reply(response);
};
- return handler;
+ return handler;
};
-internals.absolutePath = function (route) {
+internals.absolutePath = function (route) {
Utils.assert(route.server.settings.files && route.server.settings.files.relativeTo && ['routes', 'process'].indexOf(route.server.settings.files.relativeTo) !== -1, 'Invalid server files.relativeTo configuration');
+ // Plugin
+
+ if (route.env.path) {
+ return route.env.path;
+ }
+
// 'routes'
- if (route.server.settings.files.relativeTo === 'routes') {
- return internals.getRouteSourceFilePath();
+ if (route.server.settings.files.relativeTo === 'routes') {
+ return internals.getRouteSourceFilePath();
}
// 'process'
- return process.cwd();
+ return process.cwd();
};
-internals.getRouteSourceFilePath = function () {
+internals.getRouteSourceFilePath = function () {
var stack = Utils.callStack();
var callerPos = 0;
- stack.forEach(function (stackLine, i) {
+ for (var i = 0, il = stack.length; i < il; ++i) {
+ var stackLine = stack[i];
+ if (stackLine[3] &&
+ stackLine[3].indexOf('internals.Server.route') !== -1) { // The file that added the route will appear after the call to route
- if (stackLine[3] && stackLine[3].indexOf('internals.Server.route') !== -1) { // The file that added the route will appear after the call to route
- callerPos = i + 1;
- return;
- }
- });
+ callerPos = i + 1;
+ break;
+ }
+ }
- return Path.dirname(stack[callerPos][0]);
+ return Path.dirname(stack[callerPos][0]);
};
diff --git a/lib/pack.js b/lib/pack.js
index 1e4b92a57..c1d14eac3 100755
--- a/lib/pack.js
+++ b/lib/pack.js
@@ -1,10 +1,10 @@
// Load modules
-var Fs = require('fs');
var Path = require('path');
var Events = require('events');
var Async = require('async');
var Server = require('./server');
+var Views = require('./views');
var Utils = require('./utils');
@@ -17,6 +17,7 @@ internals.defaultPermissions = {
helper: true,
state: true,
events: true,
+ views: true,
ext: false
};
@@ -27,14 +28,16 @@ exports = module.exports = internals.Pack = function (options) {
Utils.assert(!options || !options.requirePath || options.requirePath[0] === '/', 'Pack option \'requirePath\' must be an absolute path');
+ this.settings = {
+ requirePath: options.requirePath || process.cwd() + '/node_modules'
+ };
+
this.servers = []; // List of all pack server members
this.labels = {}; // Server [names] organized by labels
this.names = {}; // Servers indexed by name
this.events = new Events.EventEmitter(); // Consolidated subscription to all servers' events
- this.settings = {
- requirePath: options.requirePath || process.cwd() + '/node_modules'
- };
+ this._env = {}; // Plugin-specific environment (e.g. views manager)
return this;
};
@@ -149,6 +152,13 @@ internals.Pack.prototype._register = function (plugin, permissions, options, cal
return callback(invalid);
}
+ // Setup environment
+
+ this._env[plugin.name] = {
+ name: plugin.name,
+ path: plugin.path
+ };
+
// Add plugin to servers lists
this.servers.forEach(function (server) {
@@ -163,9 +173,7 @@ internals.Pack.prototype._register = function (plugin, permissions, options, cal
var selection = self._select(criteria, subset);
var methods = {
- version: Utils.version,
length: selection.servers.length,
- next: callback,
api: function (set) {
@@ -184,7 +192,7 @@ internals.Pack.prototype._register = function (plugin, permissions, options, cal
if (permissions.route) {
methods.route = function (options) {
- self._applySync(selection.servers, Server.prototype.route, [options]);
+ self._applySync(selection.servers, Server.prototype._route, [options, self._env[plugin.name]]);
};
}
@@ -216,9 +224,23 @@ internals.Pack.prototype._register = function (plugin, permissions, options, cal
return methods;
};
+ // Setup root pack object
+
+ var root = step();
+ root.version = Utils.version;
+
+ if (permissions.views) {
+ root.views = function (options) {
+
+ Utils.assert(!self._env[plugin.name].views, 'Cannot set plugin views manager more than once');
+ options.basePath = options.basePath || plugin.path;
+ self._env[plugin.name].views = new Views(options);
+ };
+ }
+
// Register
- plugin.register.call(null, step(), options || {}, callback);
+ plugin.register.call(null, root, options || {}, callback);
};
@@ -352,7 +374,8 @@ internals.Pack.prototype._require = function (name, permissions, options, callba
plugin = {
name: pkg.name,
version: pkg.version,
- register: mod.register
+ register: mod.register,
+ path: itemName
};
}
catch (err) {
@@ -427,13 +450,15 @@ internals.getSourceFilePath = function () {
var stack = Utils.callStack();
var callerFile = '';
- stack.forEach(function (stackLine, i) {
+ 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] === 'internals.Pack.require' || stackLine[3] === 'internals.Pack.allow.scoped.require') { // The file that calls require is next
callerFile = stack[i + 1][0];
- return;
+ break;
}
- });
+ }
return Path.dirname(callerFile);
};
\ No newline at end of file
diff --git a/lib/proxy.js b/lib/proxy.js
index 82122d9f9..7c6675ed4 100755
--- a/lib/proxy.js
+++ b/lib/proxy.js
@@ -41,7 +41,7 @@ internals.Proxy.prototype.handler = function () {
return function (request) {
- self.settings.mapUri(request, function (err, uri, query) {
+ self.settings.mapUri(request, function (err, uri) {
if (err) {
return request.reply(err);
@@ -50,9 +50,8 @@ internals.Proxy.prototype.handler = function () {
var req = request.raw.req;
var options = {
- url: uri,
+ uri: uri,
method: request.method,
- qs: query,
headers: {}
};
@@ -123,7 +122,7 @@ internals.mapUri = function (protocol, host, port) {
return function (request, callback) {
- return callback(null, baseUrl + request.path, request.query);
+ return callback(null, baseUrl + request.path + (request.query ? '?' + request.query : ''));
};
};
diff --git a/lib/request.js b/lib/request.js
index af1f72c76..91c1ab094 100755
--- a/lib/request.js
+++ b/lib/request.js
@@ -449,10 +449,13 @@ internals.Request.prototype._decorate = function (callback) {
return response;
};
- if (this.server.settings.views) {
+ if (this.server.views ||
+ this._route.env.views) {
+
this.reply.view = function (template, context, options) {
- response = Response.generate(new Response.View(self.server.views, template, context, options), process);
+ var viewsManager = self._route.env.views || self.server.views;
+ response = Response.generate(new Response.View(viewsManager, template, context, options), process);
return response;
};
}
diff --git a/lib/route.js b/lib/route.js
index 631a68540..01cfeb067 100755
--- a/lib/route.js
+++ b/lib/route.js
@@ -15,7 +15,7 @@ var Views = require('./views');
var internals = {};
-exports = module.exports = internals.Route = function (options, server) {
+exports = module.exports = internals.Route = function (options, server, env) {
var self = this;
@@ -36,6 +36,7 @@ exports = module.exports = internals.Route = function (options, server) {
});
this.server = server;
+ this.env = env || {}; // Plugin-specific environment
this.method = options.method.toLowerCase();
this.path = options.path;
this.settings.method = this.method; // Expose method in settings
diff --git a/lib/router.js b/lib/router.js
index 773b762e1..bad302a57 100755
--- a/lib/router.js
+++ b/lib/router.js
@@ -77,7 +77,7 @@ internals.Router.prototype.route = function (request) {
};
-internals.Router.prototype.add = function (configs) {
+internals.Router.prototype.add = function (configs, env) {
var self = this;
@@ -88,7 +88,7 @@ internals.Router.prototype.add = function (configs) {
var methods = {};
configs.forEach(function (config) {
- var route = new Route(config, self.server); // Do no use config beyond this point, use route members
+ var route = new Route(config, self.server, env); // Do no use config beyond this point, use route members
self.table[route.method] = self.table[route.method] || [];
diff --git a/lib/server.js b/lib/server.js
index 73e8a4d2f..211510a1b 100755
--- a/lib/server.js
+++ b/lib/server.js
@@ -309,7 +309,13 @@ internals.Server.prototype.ext = function (event, func) {
internals.Server.prototype.route = internals.Server.prototype.addRoute = internals.Server.prototype.addRoutes = function (configs) {
- this._router.add(configs);
+ this._route(configs);
+};
+
+
+internals.Server.prototype._route = function (configs, env) {
+
+ this._router.add(configs, env);
};
diff --git a/lib/views.js b/lib/views.js
index d7c25226d..1bd1a7a4d 100755
--- a/lib/views.js
+++ b/lib/views.js
@@ -14,71 +14,65 @@ var internals = {};
// Engines Manager
-internals.Engines = function (options) {
+internals.Engines = function (options) {
this.settings = options || {};
- this._engines = {};
+ this._engines = {};
};
-internals.Engines.prototype.add = function (settings, key) {
+internals.Engines.prototype.add = function (settings, key) {
key = key || settings.extension || null;
Utils.assert(settings.module, 'Engine.module must be defined');
Utils.assert(key, 'Engine.extension must be defined');
- if (typeof settings.module == 'string') {
- try {
+ if (typeof settings.module === 'string') {
+ try {
this._engines[key] = require(settings.module); // Can only require modules from hapi's package.json
}
- catch (e) {
- Utils.assert(false, 'Engine.module (' + settings.module + ') must be installed');
- }
+ catch (e) {
+ Utils.assert(false, 'Engine.module (' + settings.module + ') must be installed');
+ }
}
- else {
- this._engines[key] = settings.module;
+ else {
+ this._engines[key] = settings.module;
}
this._engines[key].suffix = '.' + key;
// Generalize engine support via map object
var funcs = Object.keys(settings.map);
- for (var i = 0, il = funcs.length; i < il; ++i) {
- if (settings.map.hasOwnProperty(funcs[i])) {
- this._engines[key][funcs[i]] = settings.map[funcs[i]](this._engines[key]);
- }
+ for (var i = 0, il = funcs.length; i < il; ++i) {
+ if (settings.map.hasOwnProperty(funcs[i])) {
+ this._engines[key][funcs[i]] = settings.map[funcs[i]](this._engines[key]);
+ }
}
- return this._engines[key];
+ return this._engines[key];
};
-internals.Engines.prototype.getExt = function (p) {
+internals.Engines.prototype.getExt = function (p) {
- if (p.indexOf('.') >= 0) {
- p = Path.extname(p).slice(1);
+ if (p.indexOf('.') >= 0) {
+ p = Path.extname(p).slice(1);
}
- return p;
+ return p;
};
-internals.Engines.prototype.get = function (extension) {
+internals.Engines.prototype.get = function (extension) {
- return this._engines[this.getExt(extension)];
-};
-
-
-internals.Engines.prototype.keys = function () {
-
- return Object.keys(this._engines);
+ return this._engines[this.getExt(extension)];
};
// View Manager
-exports = module.exports = internals.Manager = function (options) {
+exports = module.exports = internals.Manager = function (options) {
this.settings = this.mergeLeft(Defaults.views, options);
@@ -91,198 +85,198 @@ exports = module.exports = internals.Manager = function (options) {
this.loadEngines();
this.loadPartials();
- return this;
+ return this;
};
-internals.Manager.prototype.mergeLeft = function () {
+internals.Manager.prototype.mergeLeft = function () {
var args = Array.prototype.slice.call(arguments);
var base = Utils.clone(args.shift());
- args.forEach(function (el, i, arr) {
+ args.forEach(function (el, i, arr) {
- for (var key in el) {
- base[key] = el[key];
- }
+ for (var key in el) {
+ base[key] = el[key];
+ }
});
- return base;
+ return base;
};
-internals.Manager.prototype.loadEngines = function () {
+internals.Manager.prototype.loadEngines = function () {
this.settings.engines = this.settings.engines || {};
// Support API backwards compatibility
- if (this.settings.engine) {
+ if (this.settings.engine) {
this.settings.engines[this.settings.engine.extension || Defaults.views.engines.html.extension] = this.settings.engine;
- delete this.settings.engine;
+ delete this.settings.engine;
}
// Load all engines
var engines = Object.keys(this.settings.engines);
- for (var i = 0, il = engines.length; i < il; ++i) {
+ for (var i = 0, il = engines.length; i < il; ++i) {
var key = engines[i];
var engine = this.settings.engines[key];
- if (!engine.extension) {
- engine.extension = key;
+ if (!engine.extension) {
+ engine.extension = key;
}
// Merge Base
var base = Utils.clone(Defaults.views.engines.html);
var baseMethods = Object.keys(base);
- for (var j = 0, jl = baseMethods.length; j < jl; ++j) {
+ for (var j = 0, jl = baseMethods.length; j < jl; ++j) {
var method = baseMethods[j];
- if (!engine.hasOwnProperty(method)) {
- engine[method] = base[method];
- }
+ if (!engine.hasOwnProperty(method)) {
+ engine[method] = base[method];
+ }
}
- this.engines.add(engine);
- }
+ this.engines.add(engine);
+ }
};
-internals.Manager.prototype.execute = function (engine, compiled, ctx, options) {
+internals.Manager.prototype.execute = function (engine, compiled, ctx, options) {
- if (engine && engine.hasOwnProperty('execute') && typeof engine.execute == 'function') {
- return engine.execute(engine, compiled, ctx, options);
- }
- else {
- return compiled;
+ if (engine && engine.hasOwnProperty('execute') && typeof engine.execute === 'function') {
+ return engine.execute(engine, compiled, ctx, options);
}
+
+ return compiled;
};
-internals.Manager.prototype.render = function (filename, context, options) {
+internals.Manager.prototype.render = function (filename, context, options) {
var template = filename;
- if (typeof template === 'string') {
+ if (typeof template === 'string') {
template = this._get(template, options);
- if (template instanceof Error) {
- return template;
- }
+ if (template instanceof Error) {
+ return template;
+ }
}
+
var engine = this.engines.get(this.engineLookup[filename]);
if (!this.settings.layout) {
// No layout
- try {
- return this.execute(engine, template, context, options)(context, options);
- }
- catch (err) {
- return Boom.internal(err.message, err);
+ try {
+ return this.execute(engine, template, context, options)(context, options);
}
+ catch (err) {
+ return Boom.internal(err.message, err);
+ }
}
// With layout
if (context &&
- context.hasOwnProperty(this.settings.layoutKeyword)) {
+ context.hasOwnProperty(this.settings.layoutKeyword)) {
- return Boom.internal('settings.layoutKeyword conflict', { context: context, keyword: this.settings.layoutKeyword });
+ return Boom.internal('settings.layoutKeyword conflict', { context: context, keyword: this.settings.layoutKeyword });
}
var layout = this._get('layout', options);
- if (layout instanceof Error) {
- return layout;
+ if (layout instanceof Error) {
+ return layout;
}
var layoutContext = Utils.clone(context);
- try {
+ try {
layoutContext[this.settings.layoutKeyword] = this.execute(engine, template, context, options)(context);
- return this.execute(engine, layout, layoutContext, options)(layoutContext);
- }
- catch (err) {
- return Boom.internal(err.message, err);
+ return this.execute(engine, layout, layoutContext, options)(layoutContext);
}
+ catch (err) {
+ return Boom.internal(err.message, err);
+ }
};
-internals.Manager.prototype._isCaching = function (filename, globalSettings, engineSettings, set) {
+internals.Manager.prototype._isCaching = function (filename, globalSettings, engineSettings, set) {
set = set || false;
engineSettings = this.mergeLeft(Defaults.views.engines.html, engineSettings || {});
- if (globalSettings.cache == false) {
+ if (globalSettings.cache === false) {
return false; // if global cache disabled, disable all caching behavior
}
- if (engineSettings.cache == false) {
+ if (engineSettings.cache === false) {
return false; // if engine cache disabled, disable this request
}
- if (set) {
- return true;
+ if (set) {
+ return true;
}
return this._cache.hasOwnProperty(filename); // Cache enabled only if key exists
};
-internals.Manager.prototype.getCache = function (filename) {
+internals.Manager.prototype.getCache = function (filename) {
- return this._cache[filename];
+ return this._cache[filename];
};
-internals.Manager.prototype.setCache = function (filename, compiled, options, engineSettings) {
+internals.Manager.prototype.setCache = function (filename, compiled, options, engineSettings) {
- if (this._isCaching(filename, options, engineSettings, true)) {
- return this._cache[filename] = compiled;
- }
+ if (this._isCaching(filename, options, engineSettings, true)) {
+ return this._cache[filename] = compiled;
+ }
};
-internals.Manager.prototype._get = function (filename, options) {
+internals.Manager.prototype._get = function (filename, options) {
options = this.mergeLeft(this.settings, options);
- if (this._isCaching(filename, options)) {
- return this.getCache(filename);
+ if (this._isCaching(filename, options)) {
+ return this.getCache(filename);
}
// Normalize path
- var isAbsolutePath = (filename.indexOf('/') === 0);
+ var isAbsolutePath = (filename[0] === '/');
var isInsecurePath = filename.match(/\.\.\//g) !== null;
if (!options.allowAbsolutePaths &&
- isAbsolutePath) {
+ isAbsolutePath) {
- return Boom.internal('Absolute paths are not allowed in views');
+ return Boom.internal('Absolute paths are not allowed in views');
}
if (!options.allowInsecureAccess &&
- isInsecurePath) {
+ isInsecurePath) {
- return Boom.internal('View paths cannot lookup templates outside root path (path includes one or more \'../\')');
+ return Boom.internal('View paths cannot lookup templates outside root path (path includes one or more \'../\')');
}
- // Resolve Path and extension
+ // Resolve path and extension
var fullPath = filename;
- if (!isAbsolutePath) {
- fullPath = Path.join(options.path, fullPath);
+ if (!isAbsolutePath) {
+ fullPath = Path.join(options.basePath, options.path, fullPath);
}
var folder = Path.dirname(fullPath);
var files = Fs.readdirSync(folder);
var re = new RegExp(Path.basename(filename) + '([.][a-zA-Z0-9]+)?$');
- for (var j = 0, jl = files.length; j < jl; ++j) {
+ for (var j = 0, jl = files.length; j < jl; ++j) {
var match = re.exec(files[j]);
- if (match) {
+ if (match) {
fullPath = Path.join(folder, files[j]);
- break;
- }
+ break;
+ }
}
// Pass the filename to Jade via this copy of compileOptions
@@ -291,11 +285,11 @@ internals.Manager.prototype._get = function (filename, options) {
// Read file
- try {
- var source = Fs.readFileSync(fullPath).toString(this.settings.encoding);
+ try {
+ var source = Fs.readFileSync(fullPath).toString(this.settings.encoding);
}
- catch (e) {
- return Boom.internal('View file not found: ' + fullPath);
+ catch (e) {
+ return Boom.internal('View file not found: ' + fullPath);
}
var engine = this.engines.get(fullPath);
@@ -304,91 +298,82 @@ internals.Manager.prototype._get = function (filename, options) {
this.setCache(filename, compiled, options, this.settings.engines[engine.suffix.slice(1)]);
- return compiled;
+ return compiled;
};
-internals.Manager.prototype.loadPartials = function () {
+internals.Manager.prototype.loadPartials = function () {
var self = this;
- if (this.settings.partials) {
- this._loadPartials(this.settings.partials.path || this.settings.path, function (files) {
-
- for (var i = 0, il = files.length; i < il; ++i) {
- var file = files[i];
- var engine = self.engines.get(file);
- if (!engine.hasOwnProperty('registerPartial')) {
- continue;
- }
-
- var name = file;
- if (name.indexOf(self.settings.partials.path) >= 0) {
- var offset = 1;
- if (self.settings.partials.path.slice(-1) == '/') {
- offset = 0;
- }
- name = name.slice(self.settings.partials.path.length + offset, -engine.suffix.length);
- }
-
- var src = Fs.readFileSync(file).toString(self.settings.encoding);
- engine.registerPartial(name, src);
- }
- });
- }
-};
-
-internals.Manager.prototype._loadPartials = function (path, callback) {
-
- var self = this;
- var suffixes = Object.keys(this.engines.keys());
-
- var walk = function (root, currentPath, files) {
+ if (!this.settings.partials) {
+ return;
+ }
+
+ var path = Path.join(this.settings.basePath, this.settings.partials.path);
+
+ var load = function (root, currentPath, files) {
var current = Path.join(root, currentPath);
- if (!Fs.statSync(current).isDirectory()) {
- try {
+ if (!Fs.statSync(current).isDirectory()) {
+ try {
var engine = self.engines.get(current);
- if (current.slice(-engine.suffix.length) === engine.suffix) {
- files.push(current);
- }
+ if (current.slice(-engine.suffix.length) === engine.suffix) {
+ files.push(current);
+ }
}
catch (e) {
// Skip file
}
- return callback(files);
+ return register(files);
}
var directory = Fs.readdirSync(current);
- for (var i = 0, il = directory.length; i < il; ++i) {
+ for (var i = 0, il = directory.length; i < il; ++i) {
var currentFile = directory[i];
var currentFileFullPath = Path.join(root, currentFile);
- if (Fs.statSync(currentFileFullPath).isDirectory()) {
- walk(currentFileFullPath, '/', files);
- }
- else {
- walk(root, currentFile, files);
+ if (Fs.statSync(currentFileFullPath).isDirectory()) {
+ load(currentFileFullPath, '/', files);
}
+ else {
+ load(root, currentFile, files);
+ }
}
- return callback(files);
+ return register(files);
};
+
+ var register = function (files) {
+
+ for (var i = 0, il = files.length; i < il; ++i) {
+ var file = files[i];
+ var engine = self.engines.get(file);
+ if (!engine.hasOwnProperty('registerPartial')) {
+ continue;
+ }
- walk(path, '/', []);
+ var offset = path.slice(-1) === '/' ? 0 : 1;
+ var name = file.slice(path.length + offset, -engine.suffix.length);
+ var src = Fs.readFileSync(file).toString(self.settings.encoding);
+ engine.registerPartial(name, src);
+ }
+ };
+
+ load(path, '/', []);
};
-exports.handler = function (route, viewFilePath) {
+exports.handler = function (route, viewFilePath) {
- return function (request) {
+ return function (request) {
- var context = {
+ var context = {
params: request.params,
payload: request.payload,
- querystring: request.querystring
+ querystring: request.querystring
};
- request.reply.view(viewFilePath, context).send();
- };
+ request.reply.view(viewFilePath, context).send();
+ };
};
diff --git a/package.json b/package.json
index 1bb3b71ed..0aa05f4aa 100755
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "hapi",
"description": "HTTP Server framework",
"homepage": "http://hapijs.com",
- "version": "0.14.3",
+ "version": "0.15.0",
"author": "Eran Hammer (http://hueniverse.com)",
"contributors": [
"Van Nguyen ",
diff --git a/test/integration/pack.js b/test/integration/pack.js
index 93b1ca415..e26b6dc88 100755
--- a/test/integration/pack.js
+++ b/test/integration/pack.js
@@ -170,6 +170,25 @@ describe('Pack', function () {
});
});
+ it('requires plugin with views', function (done) {
+
+ var server = new Hapi.Server();
+ server.plugin().require({ './pack/--views': { message: 'viewing it' } }, function (err) {
+
+ expect(err).to.not.exist;
+ server.inject({ method: 'GET', url: '/view' }, function (res) {
+
+ expect(res.result).to.equal('viewing it
');
+
+ server.inject({ method: 'GET', url: '/file' }, function (res) {
+
+ expect(res.readPayload()).to.equal('{{message}}
');
+ done();
+ });
+ });
+ });
+ });
+
it('fails to require missing module', function (done) {
var server1 = new Hapi.Server();
diff --git a/test/integration/pack/--views/lib/index.js b/test/integration/pack/--views/lib/index.js
new file mode 100755
index 000000000..1356e94fd
--- /dev/null
+++ b/test/integration/pack/--views/lib/index.js
@@ -0,0 +1,24 @@
+// Declare internals
+
+var internals = {};
+
+
+// Plugin registration
+
+exports.register = function (pack, options, next) {
+
+ pack.views({ path: './templates' });
+ pack.route([
+ {
+ path: '/view', method: 'GET', handler: function () {
+
+ return this.reply.view('test', { message: options.message }).send();
+ }
+ },
+ {
+ path: '/file', method: 'GET', handler: { file: './templates/test.html' }
+ }
+ ]);
+
+ return next();
+};
diff --git a/test/integration/pack/--views/package.json b/test/integration/pack/--views/package.json
new file mode 100755
index 000000000..857beb4d7
--- /dev/null
+++ b/test/integration/pack/--views/package.json
@@ -0,0 +1,7 @@
+{
+ "name": "--views",
+ "description": "Test plugin module",
+ "version": "0.0.1",
+ "private": true,
+ "main": "lib/index"
+}
diff --git a/test/integration/pack/--views/templates/test.html b/test/integration/pack/--views/templates/test.html
new file mode 100755
index 000000000..73d402995
--- /dev/null
+++ b/test/integration/pack/--views/templates/test.html
@@ -0,0 +1 @@
+{{message}}
\ No newline at end of file
diff --git a/test/integration/response.js b/test/integration/response.js
index c8b3f4783..cce814595 100755
--- a/test/integration/response.js
+++ b/test/integration/response.js
@@ -17,13 +17,13 @@ var internals = {};
var expect = Chai.expect;
-describe('Response', function () {
+describe('Response', function () {
- describe('Text', function () {
+ describe('Text', function () {
- it('returns a text reply', function (done) {
+ it('returns a text reply', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
request.reply.payload('text')
.type('text/plain')
@@ -31,26 +31,26 @@ describe('Response', function () {
.state('sid', 'abcdefg123456')
.state('other', 'something', { isSecure: true })
.unstate('x')
- .send();
+ .send();
};
- var handlerBound = function () {
+ var handlerBound = function () {
- this.reply('Tada');
+ this.reply('Tada');
};
var server = new Hapi.Server({ cache: { engine: 'memory' }, cors: { origin: ['test.example.com', 'www.example.com'] } });
server.route({ method: 'GET', path: '/', config: { handler: handler, cache: { mode: 'client', expiresIn: 9999 } } });
server.route({ method: 'GET', path: '/bound', config: { handler: handlerBound } });
server.state('sid', { encoding: 'base64' });
- server.ext('onPostHandler', function (request, next) {
+ server.ext('onPostHandler', function (request, next) {
request.setState('test', '123');
request.clearState('empty');
- next();
+ next();
});
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.result).to.exist;
expect(res.result).to.equal('text');
@@ -59,126 +59,126 @@ describe('Response', function () {
expect(res.headers['Access-Control-Allow-Credentials']).to.not.exist;
expect(res.headers['Set-Cookie']).to.deep.equal(['sid=YWJjZGVmZzEyMzQ1Ng==', 'other=something; Secure', 'x=; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT', "test=123", "empty=; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT"]);
- server.inject({ method: 'GET', url: '/bound', headers: { origin: 'www.example.com' } }, function (res) {
+ server.inject({ method: 'GET', url: '/bound', headers: { origin: 'www.example.com' } }, function (res) {
expect(res.result).to.exist;
expect(res.result).to.equal('Tada');
expect(res.headers['Access-Control-Allow-Origin']).to.equal('www.example.com');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a text reply when sending a buffer', function (done) {
+ it('returns a text reply when sending a buffer', function (done) {
- var handler = function () {
+ var handler = function () {
- this.reply(new Buffer('Tada'));
+ this.reply(new Buffer('Tada'));
};
var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', config: { handler: handler } });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.result).to.equal('Tada');
- done();
- });
+ done();
+ });
});
- it('returns an error on bad cookie', function (done) {
+ it('returns an error on bad cookie', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
request.reply.payload('text')
.state(';sid', 'abcdefg123456')
- .send();
+ .send();
};
var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', config: { handler: handler } });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.result).to.exist;
expect(res.result.message).to.equal('An internal server error occurred');
expect(res.headers['Set-Cookie']).to.not.exist;
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('Obj', function () {
+ describe('Obj', function () {
- it('returns an JSONP response', function (done) {
+ it('returns an JSONP response', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
- request.reply({ some: 'value' });
+ request.reply({ some: 'value' });
};
var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', config: { jsonp: 'callback', handler: handler } });
- server.inject({ method: 'GET', url: '/?callback=me' }, function (res) {
+ server.inject({ method: 'GET', url: '/?callback=me' }, function (res) {
expect(res.readPayload()).to.equal('me({"some":"value"});');
expect(res.headers['Content-Length']).to.equal(21);
- done();
- });
+ done();
+ });
});
- it('returns response on bad JSONP parameter', function (done) {
+ it('returns response on bad JSONP parameter', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
- request.reply({ some: 'value' });
+ request.reply({ some: 'value' });
};
var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', config: { jsonp: 'callback', handler: handler } });
- server.inject({ method: 'GET', url: '/?callback=me*' }, function (res) {
+ server.inject({ method: 'GET', url: '/?callback=me*' }, function (res) {
expect(res.result).to.exist;
expect(res.result.message).to.equal('Invalid JSONP parameter value');
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('Error', function () {
+ describe('Error', function () {
- it('returns an error reply', function (done) {
+ it('returns an error reply', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
- request.reply.payload(new Error('boom')).send();
+ request.reply.payload(new Error('boom')).send();
};
var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', handler: handler });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.statusCode).to.equal(500);
expect(res.result).to.exist;
expect(res.result.message).to.equal('boom');
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('Empty', function () {
+ describe('Empty', function () {
- var handler = function (request) {
+ var handler = function (request) {
- if (request.query.x) {
- return request.reply.send();
+ if (request.query.x) {
+ return request.reply.send();
}
- return request.reply();
+ return request.reply();
};
var server = new Hapi.Server({ cors: { credentials: true } });
@@ -186,31 +186,31 @@ describe('Response', function () {
{ method: 'GET', path: '/', handler: handler },
]);
- it('returns an empty reply', function (done) {
+ it('returns an empty reply', function (done) {
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.result).to.not.exist;
expect(res.headers['Access-Control-Allow-Credentials']).to.equal('true');
- done();
- });
+ done();
+ });
});
- it('returns an empty reply (long form)', function (done) {
+ it('returns an empty reply (long form)', function (done) {
- server.inject({ method: 'GET', url: '/?x=1' }, function (res) {
+ server.inject({ method: 'GET', url: '/?x=1' }, function (res) {
expect(res.result).to.not.exist;
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('Raw', function () {
+ describe('Raw', function () {
- it('returns a reply', function (done) {
+ it('returns a reply', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
var response = new Hapi.Response.Raw(request)
.type('text/plain')
@@ -218,32 +218,32 @@ describe('Response', function () {
.ttl(1000)
.state('sid', 'abcdefg123456');
- response.begin(function (err) {
+ response.begin(function (err) {
response.write('!hola ')
.write('amigos!');
- request.reply(response);
- });
+ request.reply(response);
+ });
};
var server = new Hapi.Server({ cors: { origin: ['test.example.com'] } });
server.route({ method: 'GET', path: '/', config: { handler: handler, cache: { mode: 'client', expiresIn: 9999 } } });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.statusCode).to.equal(200);
expect(res.headers['set-cookie']).to.deep.equal(['sid=abcdefg123456']);
expect(res.readPayload()).to.equal('!hola amigos!');
expect(res.headers['cache-control']).to.equal('max-age=1, must-revalidate');
expect(res.headers['access-control-allow-origin']).to.equal('test.example.com');
- done();
- });
+ done();
+ });
});
- it('returns a reply using send()', function (done) {
+ it('returns a reply using send()', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
var response = request.reply.raw();
response.type('text/plain')
@@ -251,31 +251,31 @@ describe('Response', function () {
.ttl(1000)
.state('sid', 'abcdefg123456');
- response.begin(function (err) {
+ response.begin(function (err) {
response.write('!hola ')
.write('amigos!')
- .send();
- });
+ .send();
+ });
};
var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', config: { handler: handler, cache: { mode: 'client', expiresIn: 9999 } } });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.statusCode).to.equal(200);
expect(res.headers['set-cookie']).to.deep.equal(['sid=abcdefg123456']);
expect(res.readPayload()).to.equal('!hola amigos!');
expect(res.headers['cache-control']).to.equal('max-age=1, must-revalidate');
expect(res.headers['access-control-allow-origin']).to.not.exist;
- done();
- });
+ done();
+ });
});
- it('returns a reply with no payload', function (done) {
+ it('returns a reply with no payload', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
var response = new Hapi.Response.Raw(request)
.code(299)
@@ -283,25 +283,25 @@ describe('Response', function () {
.bytes(13)
.state('sid', 'abcdefg123456');
- request.reply(response);
+ request.reply(response);
};
var server = new Hapi.Server({ cors: { origin: ['test.example.com'] } });
server.route({ method: 'GET', path: '/', config: { handler: handler } });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.statusCode).to.equal(299);
expect(res.headers['set-cookie']).to.deep.equal(['sid=abcdefg123456']);
expect(res.readPayload()).to.equal('');
expect(res.headers['access-control-allow-origin']).to.equal('test.example.com');
- done();
- });
+ done();
+ });
});
- it('returns a HEAD reply', function (done) {
+ it('returns a HEAD reply', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
var response = new Hapi.Response.Raw(request)
.type('text/plain')
@@ -309,32 +309,32 @@ describe('Response', function () {
.ttl(1000)
.state('sid', 'abcdefg123456');
- response.begin(function (err) {
+ response.begin(function (err) {
response.write('!hola ')
.write('amigos!');
- request.reply(response);
- });
+ request.reply(response);
+ });
};
var server = new Hapi.Server({ cors: { origin: ['test.example.com'] } });
server.route({ method: 'GET', path: '/', config: { handler: handler, cache: { mode: 'client', expiresIn: 9999 } } });
- server.inject({ method: 'HEAD', url: '/' }, function (res) {
+ server.inject({ method: 'HEAD', url: '/' }, function (res) {
expect(res.statusCode).to.equal(200);
expect(res.headers['set-cookie']).to.deep.equal(['sid=abcdefg123456']);
expect(res.readPayload()).to.equal('');
expect(res.headers['cache-control']).to.equal('max-age=1, must-revalidate');
expect(res.headers['access-control-allow-origin']).to.equal('test.example.com');
- done();
- });
+ done();
+ });
});
- it('returns a reply (created)', function (done) {
+ it('returns a reply (created)', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
var response = new Hapi.Response.Raw(request)
.created('me')
@@ -343,19 +343,19 @@ describe('Response', function () {
.ttl(1000)
.state('sid', 'abcdefg123456');
- response.begin(function (err) {
+ response.begin(function (err) {
response.write('!hola ')
.write('amigos!');
- request.reply(response);
- });
+ request.reply(response);
+ });
};
var server = new Hapi.Server({ cors: { origin: ['test.example.com'] } });
server.route({ method: 'GET', path: '/', config: { handler: handler, cache: { mode: 'client', expiresIn: 9999 } } });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.statusCode).to.equal(201);
expect(res.headers.location).to.equal(server.settings.uri + '/me');
@@ -363,245 +363,245 @@ describe('Response', function () {
expect(res.readPayload()).to.equal('!hola amigos!');
expect(res.headers['cache-control']).to.equal('no-cache');
expect(res.headers['access-control-allow-origin']).to.equal('test.example.com');
- done();
- });
+ done();
+ });
});
- it('returns a error on bad cookie', function (done) {
+ it('returns a error on bad cookie', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
var response = new Hapi.Response.Raw(request)
.bytes(13)
.state(';sid', 'abcdefg123456');
- response.begin(function (err) {
+ response.begin(function (err) {
response.write('!hola ')
.write('amigos!');
- request.reply(response);
- });
+ request.reply(response);
+ });
};
var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', config: { handler: handler } });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.statusCode).to.equal(200); // Too late to change at this point
expect(res.headers['Set-Cookie']).to.not.exist;
expect(res.readPayload()).to.equal('!hola amigos!');
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('File', function () {
+ describe('File', function () {
- it('returns a file in the response with the correct headers', function (done) {
+ it('returns a file in the response with the correct headers', function (done) {
- var server = new Hapi.Server(0);
- var handler = function (request) {
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
+ var handler = function (request) {
- request.reply(new Hapi.Response.File(__dirname + '/../../package.json'));
+ request.reply(new Hapi.Response.File(__dirname + '/../../package.json'));
};
server.route({ method: 'GET', path: '/file', handler: handler });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/file', function (err, res, body) {
+ Request.get(server.settings.uri + '/file', function (err, res, body) {
expect(err).to.not.exist;
expect(body).to.contain('hapi');
expect(res.headers['content-type']).to.equal('application/json');
expect(res.headers['content-length']).to.exist;
expect(res.headers['content-disposition']).to.equal('inline; filename=package.json');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a file in the response with the correct headers using process relative paths', function (done) {
+ it('returns a file in the response with the correct headers using process relative paths', function (done) {
var server = new Hapi.Server(0, { files: { relativeTo: 'process' } });
server.route({ method: 'GET', path: '/', handler: { file: './package.json' } });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri, function (err, res, body) {
+ Request.get(server.settings.uri, function (err, res, body) {
expect(err).to.not.exist;
expect(body).to.contain('hapi');
expect(res.headers['content-type']).to.equal('application/json');
expect(res.headers['content-length']).to.exist;
expect(res.headers['content-disposition']).to.equal('inline; filename=package.json');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a 404 when the file is not found', function (done) {
+ it('returns a 404 when the file is not found', function (done) {
- var server = new Hapi.Server(0);
- var notFoundHandler = function (request) {
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
+ var notFoundHandler = function (request) {
- request.reply(new Hapi.Response.File(__dirname + '/../../notHere'));
+ request.reply(new Hapi.Response.File(__dirname + '/../../notHere'));
};
server.route({ method: 'GET', path: '/filenotfound', handler: notFoundHandler });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/filenotfound', function (err, res) {
+ Request.get(server.settings.uri + '/filenotfound', function (err, res) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(404);
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a 403 when the file is a directory', function (done) {
+ it('returns a 403 when the file is a directory', function (done) {
- var server = new Hapi.Server(0);
- var folderHandler = function (request) {
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
+ var folderHandler = function (request) {
- request.reply(new Hapi.Response.File(__dirname));
+ request.reply(new Hapi.Response.File(__dirname));
};
server.route({ method: 'GET', path: '/filefolder', handler: folderHandler });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/filefolder', function (err, res) {
+ Request.get(server.settings.uri + '/filefolder', function (err, res) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(403);
- done();
- });
- });
+ done();
+ });
+ });
});
- var filenameFn = function (request) {
+ var filenameFn = function (request) {
- return '../../' + request.params.file;
+ return '../../' + request.params.file;
};
- it('returns a file using the build-in handler config', function (done) {
+ it('returns a file using the build-in handler config', function (done) {
- var server = new Hapi.Server(0);
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
server.route({ method: 'GET', path: '/staticfile', handler: { file: __dirname + '/../../package.json' } });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/staticfile', function (err, res, body) {
+ Request.get(server.settings.uri + '/staticfile', function (err, res, body) {
expect(err).to.not.exist;
expect(body).to.contain('hapi');
expect(res.headers['content-type']).to.equal('application/json');
expect(res.headers['content-length']).to.exist;
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a file using the file function with the build-in handler config', function (done) {
+ it('returns a file using the file function with the build-in handler config', function (done) {
- var server = new Hapi.Server(0);
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
server.route({ method: 'GET', path: '/filefn/{file}', handler: { file: filenameFn } });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/filefn/index.js', function (err, res, body) {
+ Request.get(server.settings.uri + '/filefn/index.js', function (err, res, body) {
expect(err).to.not.exist;
expect(body).to.contain('./lib');
expect(res.headers['content-type']).to.equal('application/javascript');
expect(res.headers['content-length']).to.exist;
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a file in the response with the correct headers (relative path)', function (done) {
+ it('returns a file in the response with the correct headers (relative path)', function (done) {
- var server = new Hapi.Server(0);
- var relativeHandler = function (request) {
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
+ var relativeHandler = function (request) {
- request.reply(new Hapi.Response.File('./package.json'));
+ request.reply(new Hapi.Response.File('./package.json'));
};
server.route({ method: 'GET', path: '/relativefile', handler: relativeHandler });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/relativefile', function (err, res, body) {
+ Request.get(server.settings.uri + '/relativefile', function (err, res, body) {
expect(err).to.not.exist;
expect(body).to.contain('hapi');
expect(res.headers['content-type']).to.equal('application/json');
expect(res.headers['content-length']).to.exist;
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a file using the built-in handler config (relative path)', function (done) {
+ it('returns a file using the built-in handler config (relative path)', function (done) {
- var server = new Hapi.Server(0);
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
server.route({ method: 'GET', path: '/relativestaticfile', handler: { file: '../../package.json' } });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/relativestaticfile', function (err, res, body) {
+ Request.get(server.settings.uri + '/relativestaticfile', function (err, res, body) {
expect(err).to.not.exist;
expect(body).to.contain('hapi');
expect(res.headers['content-type']).to.equal('application/json');
expect(res.headers['content-length']).to.exist;
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a 304 when the request has a matching etag', function (done) {
+ it('returns a 304 when the request has a matching etag', function (done) {
- var server = new Hapi.Server(0);
- var handler = function (request) {
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
+ var handler = function (request) {
- request.reply(new Hapi.Response.File(__dirname + '/../../package.json'));
+ request.reply(new Hapi.Response.File(__dirname + '/../../package.json'));
};
server.route({ method: 'GET', path: '/file', handler: handler });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/file', function (err, res1) {
+ Request.get(server.settings.uri + '/file', function (err, res1) {
- var headers = {
- 'if-none-match': res1.headers.etag
+ var headers = {
+ 'if-none-match': res1.headers.etag
};
- Request.get({ url: server.settings.uri + '/file', headers: headers }, function (err, res2) {
+ Request.get({ url: server.settings.uri + '/file', headers: headers }, function (err, res2) {
expect(res2.statusCode).to.equal(304);
- done();
- });
- });
- });
+ done();
+ });
+ });
+ });
});
- it('invalidates etags when file changes', function (done) {
+ it('invalidates etags when file changes', function (done) {
- var server = new Hapi.Server();
+ var server = new Hapi.Server({ files: { relativeTo: 'routes' } });
server.route({ method: 'GET', path: '/note', handler: { file: './file/note.txt' } });
// No etag, never requested
- server.inject({ method: 'GET', url: '/note' }, function (res1) {
+ server.inject({ method: 'GET', url: '/note' }, function (res1) {
expect(res1.statusCode).to.equal(200);
expect(res1.readPayload()).to.equal('Test');
@@ -609,7 +609,7 @@ describe('Response', function () {
// No etag, previously requested
- server.inject({ method: 'GET', url: '/note' }, function (res2) {
+ server.inject({ method: 'GET', url: '/note' }, function (res2) {
expect(res2.statusCode).to.equal(200);
expect(res2.readPayload()).to.equal('Test');
@@ -619,7 +619,7 @@ describe('Response', function () {
// etag
- server.inject({ method: 'GET', url: '/note', headers: { 'if-none-match': etag1 } }, function (res3) {
+ server.inject({ method: 'GET', url: '/note', headers: { 'if-none-match': etag1 } }, function (res3) {
expect(res3.statusCode).to.equal(304);
@@ -629,7 +629,7 @@ describe('Response', function () {
// etag after file modified, content unchanged
- server.inject({ method: 'GET', url: '/note', headers: { 'if-none-match': etag1 } }, function (res4) {
+ server.inject({ method: 'GET', url: '/note', headers: { 'if-none-match': etag1 } }, function (res4) {
expect(res4.statusCode).to.equal(200);
expect(res4.readPayload()).to.equal('Test');
@@ -637,7 +637,7 @@ describe('Response', function () {
// No etag, previously requested
- server.inject({ method: 'GET', url: '/note' }, function (res5) {
+ server.inject({ method: 'GET', url: '/note' }, function (res5) {
expect(res5.statusCode).to.equal(200);
expect(res5.readPayload()).to.equal('Test');
@@ -652,7 +652,7 @@ describe('Response', function () {
// etag after file modified, content changed
- server.inject({ method: 'GET', url: '/note', headers: { 'if-none-match': etag2 } }, function (res6) {
+ server.inject({ method: 'GET', url: '/note', headers: { 'if-none-match': etag2 } }, function (res6) {
expect(res6.statusCode).to.equal(200);
expect(res6.readPayload()).to.equal('Test1');
@@ -660,7 +660,7 @@ describe('Response', function () {
// No etag, previously requested
- server.inject({ method: 'GET', url: '/note' }, function (res7) {
+ server.inject({ method: 'GET', url: '/note' }, function (res7) {
expect(res7.statusCode).to.equal(200);
expect(res7.readPayload()).to.equal('Test1');
@@ -675,14 +675,14 @@ describe('Response', function () {
// No etag, content restored
- server.inject({ method: 'GET', url: '/note' }, function (res8) {
+ server.inject({ method: 'GET', url: '/note' }, function (res8) {
expect(res8.statusCode).to.equal(200);
expect(res8.readPayload()).to.equal('Test');
// No etag, previously requested
- server.inject({ method: 'GET', url: '/note' }, function (res9) {
+ server.inject({ method: 'GET', url: '/note' }, function (res9) {
expect(res9.statusCode).to.equal(200);
expect(res9.readPayload()).to.equal('Test');
@@ -691,121 +691,121 @@ describe('Response', function () {
var etag4 = res9.headers.etag;
expect(etag1).to.equal(etag4);
- done();
- });
- });
- });
- });
- });
- });
- });
- });
- });
+ done();
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
});
- it('returns a 304 when the request has if-modified-since and the response hasn\'t been modified since', function (done) {
+ it('returns a 304 when the request has if-modified-since and the response hasn\'t been modified since', function (done) {
- var server = new Hapi.Server(0);
- var handler = function (request) {
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
+ var handler = function (request) {
- request.reply(new Hapi.Response.File(__dirname + '/../../package.json'));
+ request.reply(new Hapi.Response.File(__dirname + '/../../package.json'));
};
server.route({ method: 'GET', path: '/file', handler: handler });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri, function (err, res1) {
+ Request.get(server.settings.uri, function (err, res1) {
- var headers = {
- 'if-modified-since': res1.headers.date
+ var headers = {
+ 'if-modified-since': res1.headers.date
};
- Request.get({ url: server.settings.uri + '/file', headers: headers }, function (err, res2) {
+ Request.get({ url: server.settings.uri + '/file', headers: headers }, function (err, res2) {
expect(res2.statusCode).to.equal(304);
- done();
- });
- });
- });
+ done();
+ });
+ });
+ });
});
- it('returns a gzipped file in the response when the request accepts gzip', function (done) {
+ it('returns a gzipped file in the response when the request accepts gzip', function (done) {
- var server = new Hapi.Server(0);
- var handler = function (request) {
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
+ var handler = function (request) {
- request.reply(new Hapi.Response.File(__dirname + '/../../package.json'));
+ request.reply(new Hapi.Response.File(__dirname + '/../../package.json'));
};
server.route({ method: 'GET', path: '/file', handler: handler });
- server.start(function () {
+ server.start(function () {
- Request.get({ url: server.settings.uri + '/file', headers: { 'accept-encoding': 'gzip' } }, function (err, res, body) {
+ Request.get({ url: server.settings.uri + '/file', headers: { 'accept-encoding': 'gzip' } }, function (err, res, body) {
expect(err).to.not.exist;
expect(res.headers['content-type']).to.equal('application/json');
expect(res.headers['content-encoding']).to.equal('gzip');
expect(res.headers['content-length']).to.not.exist;
expect(body).to.exist;
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a deflated file in the response when the request accepts deflate', function (done) {
+ it('returns a deflated file in the response when the request accepts deflate', function (done) {
- var server = new Hapi.Server(0);
- var handler = function (request) {
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
+ var handler = function (request) {
- request.reply(new Hapi.Response.File(__dirname + '/../../package.json'));
+ request.reply(new Hapi.Response.File(__dirname + '/../../package.json'));
};
server.route({ method: 'GET', path: '/file', handler: handler });
- server.start(function () {
+ server.start(function () {
- Request.get({ url: server.settings.uri + '/file', headers: { 'accept-encoding': 'deflate' } }, function (err, res, body) {
+ Request.get({ url: server.settings.uri + '/file', headers: { 'accept-encoding': 'deflate' } }, function (err, res, body) {
expect(err).to.not.exist;
expect(res.headers['content-type']).to.equal('application/json');
expect(res.headers['content-encoding']).to.equal('deflate');
expect(res.headers['content-length']).to.not.exist;
expect(body).to.exist;
- done();
- });
- });
+ done();
+ });
+ });
});
- it('throws an error when adding a route with a parameter and string path', function (done) {
+ it('throws an error when adding a route with a parameter and string path', function (done) {
- var fn = function () {
+ var fn = function () {
- var server = new Hapi.Server(0);
- server.route({ method: 'GET', path: '/fileparam/{path}', handler: { file: './package.json' } });
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
+ server.route({ method: 'GET', path: '/fileparam/{path}', handler: { file: './package.json' } });
};
expect(fn).to.throw(Error);
- done();
+ done();
});
- it('doesn\'t throw an error when adding a route with a parameter and function path', function (done) {
+ it('doesn\'t throw an error when adding a route with a parameter and function path', function (done) {
- var fn = function () {
+ var fn = function () {
- var server = new Hapi.Server(0);
- server.route({ method: 'GET', path: '/fileparam/{path}', handler: { file: function () { } } });
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
+ server.route({ method: 'GET', path: '/fileparam/{path}', handler: { file: function () { } } });
};
expect(fn).to.not.throw(Error);
- done();
- });
+ done();
+ });
});
- describe('Directory', function () {
+ describe('Directory', function () {
- var server = new Hapi.Server(0);
+ var server = new Hapi.Server(0, { files: { relativeTo: 'routes' } });
server.route({ method: 'GET', path: '/directory/{path*}', handler: { directory: { path: '.' } } }); // Use '.' to test path normalization
server.route({ method: 'GET', path: '/showhidden/{path*}', handler: { directory: { path: './', showHidden: true, listing: true } } });
server.route({ method: 'GET', path: '/noshowhidden/{path*}', handler: { directory: { path: './', listing: true } } });
@@ -813,401 +813,401 @@ describe('Response', function () {
server.route({ method: 'GET', path: '/showindex/{path*}', handler: { directory: { path: './', index: true, listing: true } } });
server.route({ method: 'GET', path: '/multiple/{path*}', handler: { directory: { path: ['./', '../'], listing: true } } });
- it('returns a 403 when no index exists and listing is disabled', function (done) {
+ it('returns a 403 when no index exists and listing is disabled', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directory/', function (err, res, body) {
+ Request.get(server.settings.uri + '/directory/', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(403);
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a 403 when requesting a path containing \'..\'', function (done) {
+ it('returns a 403 when requesting a path containing \'..\'', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directory/..', function (err, res, body) {
+ Request.get(server.settings.uri + '/directory/..', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(403);
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a 404 when requesting an unknown file within a directory', function (done) {
+ it('returns a 404 when requesting an unknown file within a directory', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directory/xyz', function (err, res, body) {
+ Request.get(server.settings.uri + '/directory/xyz', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(404);
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a file when requesting a file from the directory', function (done) {
+ it('returns a file when requesting a file from the directory', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directory/response.js', function (err, res, body) {
+ Request.get(server.settings.uri + '/directory/response.js', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(200);
expect(body).to.contain('hapi');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a file when requesting a file from multi directory setup', function (done) {
+ it('returns a file when requesting a file from multi directory setup', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/multiple/unit/response/directory.js', function (err, res, body) {
+ Request.get(server.settings.uri + '/multiple/unit/response/directory.js', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(200);
expect(body).to.contain('no_such_path');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns the correct file when requesting a file from a child directory', function (done) {
+ it('returns the correct file when requesting a file from a child directory', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directory/directory/index.html', function (err, res, body) {
+ Request.get(server.settings.uri + '/directory/directory/index.html', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(200);
expect(body).to.contain('test');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns the correct listing links when viewing top level path', function (done) {
+ it('returns the correct listing links when viewing top level path', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/', function (err, res, body) {
+ Request.get(server.settings.uri + '/', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(200);
expect(body).to.contain('href="/response.js"');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('doesn\'t contain any double / when viewing sub path listing', function (done) {
+ it('doesn\'t contain any double / when viewing sub path listing', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/showindex/', function (err, res, body) {
+ Request.get(server.settings.uri + '/showindex/', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(200);
expect(body).to.not.contain('//');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('has the correct link to sub folders when inside of a sub folder listing', function (done) {
+ it('has the correct link to sub folders when inside of a sub folder listing', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/showindex/directory/subdir', function (err, res, body) {
+ Request.get(server.settings.uri + '/showindex/directory/subdir', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(200);
expect(body).to.contain('href="/showindex/directory/subdir/subsubdir"');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a 403 when index and listing are disabled', function (done) {
+ it('returns a 403 when index and listing are disabled', function (done) {
server.route({ method: 'GET', path: '/directoryx/{path*}', handler: { directory: { path: '../../', index: false } } });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directoryx/', function (err, res, body) {
+ Request.get(server.settings.uri + '/directoryx/', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(403);
- done();
- });
- });
+ done();
+ });
+ });
});
server.route({ method: 'GET', path: '/directorylist/{path*}', handler: { directory: { path: '../../', listing: true } } });
- it('returns a list of files when listing is enabled', function (done) {
+ it('returns a list of files when listing is enabled', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directorylist/', function (err, res, body) {
+ Request.get(server.settings.uri + '/directorylist/', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(200);
expect(body).to.contain('package.json');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a list of files for subdirectory', function (done) {
+ it('returns a list of files for subdirectory', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directorylist/test', function (err, res, body) {
+ Request.get(server.settings.uri + '/directorylist/test', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(200);
expect(body).to.contain('integration');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a list of files when listing is enabled and index disabled', function (done) {
+ it('returns a list of files when listing is enabled and index disabled', function (done) {
server.route({ method: 'GET', path: '/directorylistx/{path*}', handler: { directory: { path: '../../', listing: true, index: false } } });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directorylistx/', function (err, res, body) {
+ Request.get(server.settings.uri + '/directorylistx/', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(200);
expect(body).to.contain('package.json');
- done();
- });
- });
+ done();
+ });
+ });
});
server.route({ method: 'GET', path: '/directoryIndex/{path*}', handler: { directory: { path: './directory/' } } });
- it('returns the index when found', function (done) {
+ it('returns the index when found', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directoryIndex/', function (err, res, body) {
+ Request.get(server.settings.uri + '/directoryIndex/', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(200);
expect(body).to.contain('test
');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a 500 when index.html is a directory', function (done) {
+ it('returns a 500 when index.html is a directory', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directoryIndex/invalid', function (err, res, body) {
+ Request.get(server.settings.uri + '/directoryIndex/invalid', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(500);
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns the correct file when using a fn directory handler', function (done) {
+ it('returns the correct file when using a fn directory handler', function (done) {
- var directoryFn = function (request) {
+ var directoryFn = function (request) {
- return '../../lib';
+ return '../../lib';
};
server.route({ method: 'GET', path: '/directoryfn/{path?}', handler: { directory: { path: directoryFn } } });
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/directoryfn/defaults.js', function (err, res, body) {
+ Request.get(server.settings.uri + '/directoryfn/defaults.js', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(200);
expect(body).to.contain('export');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns listing with hidden files when hidden files should be shown', function (done) {
+ it('returns listing with hidden files when hidden files should be shown', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/showhidden/', function (err, res, body) {
+ Request.get(server.settings.uri + '/showhidden/', function (err, res, body) {
expect(err).to.not.exist;
expect(body).to.contain('.hidden');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns listing without hidden files when hidden files should not be shown', function (done) {
+ it('returns listing without hidden files when hidden files should not be shown', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/noshowhidden/', function (err, res, body) {
+ Request.get(server.settings.uri + '/noshowhidden/', function (err, res, body) {
expect(err).to.not.exist;
expect(body).to.not.contain('.hidden');
expect(body).to.contain('response.js');
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a 404 response when requesting a hidden file when showHidden is disabled', function (done) {
+ it('returns a 404 response when requesting a hidden file when showHidden is disabled', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/noshowhidden/.hidden', function (err, res, body) {
+ Request.get(server.settings.uri + '/noshowhidden/.hidden', function (err, res, body) {
expect(err).to.not.exist;
expect(res.statusCode).to.equal(404);
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a file when requesting a hidden file when showHidden is enabled', function (done) {
+ it('returns a file when requesting a hidden file when showHidden is enabled', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get(server.settings.uri + '/showhidden/.hidden', function (err, res, body) {
+ Request.get(server.settings.uri + '/showhidden/.hidden', function (err, res, body) {
expect(err).to.not.exist;
expect(body).to.contain('test');
- done();
- });
- });
- });
+ done();
+ });
+ });
+ });
});
- describe('Stream', function () {
+ describe('Stream', function () {
var _streamRequest = null;
- FakeStream = function (issue) {
+ FakeStream = function (issue) {
Stream.call(this);
this.pause = this.resume = this.setEncoding = function () { };
var self = this;
- this.destroy = function () {
+ this.destroy = function () {
- self.readable = false;
+ self.readable = false;
};
this.issue = issue;
- return this;
+ return this;
};
Hapi.utils.inherits(FakeStream, Stream);
- FakeStream.prototype.on = FakeStream.prototype.addListener = function (event, callback) {
+ FakeStream.prototype.on = FakeStream.prototype.addListener = function (event, callback) {
- switch (this.issue) {
+ switch (this.issue) {
case 'error':
- if (event === 'error') {
- if (!this.x) {
+ if (event === 'error') {
+ if (!this.x) {
callback();
- this.x = true;
- }
+ this.x = true;
+ }
}
break;
case 'double':
- if (event === 'data') {
+ if (event === 'data') {
callback('x');
this.x();
- this.y();
+ this.y();
}
- else if (event === 'error') {
- if (!this.x) {
- this.x = callback;
- }
+ else if (event === 'error') {
+ if (!this.x) {
+ this.x = callback;
+ }
}
- else if (event === 'end') {
- if (!this.y) {
- this.y = callback;
- }
+ else if (event === 'end') {
+ if (!this.y) {
+ this.y = callback;
+ }
}
break;
case 'closes':
- if (event === 'data') {
- callback('here is the response');
+ if (event === 'data') {
+ callback('here is the response');
}
- else if (event === 'end') {
+ else if (event === 'end') {
_streamRequest.raw.req.emit('close');
- callback();
+ callback();
}
break;
default:
- if (event === 'data') {
+ if (event === 'data') {
callback('x');
- this.x();
+ this.x();
}
- else if (event === 'end') {
- this.x = callback;
+ else if (event === 'end') {
+ this.x = callback;
}
- break;
- }
+ break;
+ }
};
- var handler = function (request) {
+ var handler = function (request) {
_streamRequest = request;
request.reply.stream(new FakeStream(request.params.issue))
.bytes(request.params.issue ? 0 : 1)
.ttl(2000)
- .send();
+ .send();
};
- var handler2 = function (request) {
+ var handler2 = function (request) {
_streamRequest = request;
var simulation = new FakeStream(request.params.issue);
- simulation.destroy = function () {
+ simulation.destroy = function () {
- simulation.readable = false;
+ simulation.readable = false;
};
- request.reply.stream(simulation).bytes(request.params.issue ? 0 : 1).send();
+ request.reply.stream(simulation).bytes(request.params.issue ? 0 : 1).send();
};
- var handler3 = function (request) {
+ var handler3 = function (request) {
_streamRequest = request;
request.reply.stream(new FakeStream(request.params.issue))
.created('/special')
.bytes(request.params.issue ? 0 : 1)
.ttl(3000)
- .send();
+ .send();
};
- var handler4 = function (request) {
+ var handler4 = function (request) {
_streamRequest = request;
request.reply.stream(new FakeStream())
.state(';sid', 'abcdefg123456')
- .send();
+ .send();
};
var server = new Hapi.Server('0.0.0.0', 19798, { cors: { origin: ['test.example.com'] } });
@@ -1216,230 +1216,229 @@ describe('Response', function () {
server.route({ method: 'GET', path: '/stream3', config: { handler: handler3, cache: { mode: 'client', expiresIn: 9999 } } });
server.route({ method: 'GET', path: '/stream4', config: { handler: handler4 } });
- it('returns a stream reply', function (done) {
+ it('returns a stream reply', function (done) {
- server.inject({ method: 'GET', url: '/stream/' }, function (res) {
+ server.inject({ method: 'GET', url: '/stream/' }, function (res) {
expect(res.readPayload()).to.equal('x');
expect(res.statusCode).to.equal(200);
expect(res.headers['Cache-Control']).to.equal('max-age=2, must-revalidate');
expect(res.headers['Access-Control-Allow-Origin']).to.equal('test.example.com');
- done();
- });
+ done();
+ });
});
- it('returns a gzipped stream reply without a content-length header when accept-encoding is gzip', function (done) {
+ it('returns a gzipped stream reply without a content-length header when accept-encoding is gzip', function (done) {
- var streamHandler = function (request) {
+ var streamHandler = function (request) {
var stream = new Stream();
stream.readable = true;
- stream.resume = function () {
+ stream.resume = function () {
- setTimeout(function () {
+ setTimeout(function () {
- stream.emit('end', 'hi');
- }, 5);
+ stream.emit('end', 'hi');
+ }, 5);
};
- request.reply.stream(stream).send();
+ request.reply.stream(stream).send();
};
var server1 = new Hapi.Server(0);
server1.route({ method: 'GET', path: '/stream', handler: streamHandler });
- server1.start(function () {
+ server1.start(function () {
- Request.get({ uri: server1.settings.uri + '/stream', headers: { 'Content-Type': 'application/json', 'accept-encoding': 'gzip' } }, function (err, res) {
+ Request.get({ uri: server1.settings.uri + '/stream', headers: { 'Content-Type': 'application/json', 'accept-encoding': 'gzip' } }, function (err, res) {
expect(res.statusCode).to.equal(200);
expect(res.headers['Content-Length']).to.not.exist;
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a deflated stream reply without a content-length header when accept-encoding is deflate', function (done) {
+ it('returns a deflated stream reply without a content-length header when accept-encoding is deflate', function (done) {
- var streamHandler = function (request) {
+ var streamHandler = function (request) {
var stream = new Stream();
stream.readable = true;
- stream.resume = function () {
+ stream.resume = function () {
- setTimeout(function () {
+ setTimeout(function () {
- stream.emit('data', 'hi');
+ stream.emit('data', 'hi');
}, 2);
- setTimeout(function () {
+ setTimeout(function () {
- request.raw.req.destroy();
- }, 5);
+ request.raw.req.destroy();
+ }, 5);
};
- request.reply.stream(stream).send();
+ request.reply.stream(stream).send();
};
var server1 = new Hapi.Server(0);
server1.route({ method: 'GET', path: '/stream', handler: streamHandler });
- server1.start(function () {
+ server1.start(function () {
- Request.get({ uri: server1.settings.uri + '/stream', headers: { 'Content-Type': 'application/json', 'accept-encoding': 'deflate' } }, function (err, res) {
+ Request.get({ uri: server1.settings.uri + '/stream', headers: { 'Content-Type': 'application/json', 'accept-encoding': 'deflate' } }, function (err, res) {
expect(res.statusCode).to.equal(200);
expect(res.headers['Content-Length']).to.not.exist;
- done();
- });
- });
+ done();
+ });
+ });
});
- it('returns a stream reply (created)', function (done) {
+ it('returns a stream reply (created)', function (done) {
- server.inject({ method: 'GET', url: '/stream3' }, function (res) {
+ server.inject({ method: 'GET', url: '/stream3' }, function (res) {
expect(res.readPayload()).to.equal('x');
expect(res.statusCode).to.equal(201);
expect(res.headers.Location).to.equal(server.settings.uri + '/special');
expect(res.headers['Cache-Control']).to.equal('no-cache');
expect(res.headers['Access-Control-Allow-Origin']).to.equal('test.example.com');
- done();
- });
+ done();
+ });
});
- it('returns an error on bad state', function (done) {
+ it('returns an error on bad state', function (done) {
- server.inject({ method: 'GET', url: '/stream4' }, function (res) {
+ server.inject({ method: 'GET', url: '/stream4' }, function (res) {
expect(res.statusCode).to.equal(500);
- done();
- });
+ done();
+ });
});
- it('returns a broken stream reply on error issue', function (done) {
+ it('returns a broken stream reply on error issue', function (done) {
- server.inject({ method: 'GET', url: '/stream/error' }, function (res) {
+ server.inject({ method: 'GET', url: '/stream/error' }, function (res) {
expect(res.readPayload()).to.equal('');
- done();
- });
+ done();
+ });
});
- it('returns a broken stream reply on double issue', function (done) {
+ it('returns a broken stream reply on double issue', function (done) {
- server.inject({ method: 'GET', url: '/stream/double' }, function (res) {
+ server.inject({ method: 'GET', url: '/stream/double' }, function (res) {
expect(res.readPayload()).to.equal('x');
- done();
- });
+ done();
+ });
});
- it('stops processing the stream when the request closes', function (done) {
+ it('stops processing the stream when the request closes', function (done) {
- server.start(function () {
+ server.start(function () {
- Request.get({ uri: 'http://127.0.0.1:19798/stream/closes', headers: { 'Accept-Encoding': 'gzip' } }, function (err, res) {
+ Request.get({ uri: 'http://127.0.0.1:19798/stream/closes', headers: { 'Accept-Encoding': 'gzip' } }, function (err, res) {
expect(res.statusCode).to.equal(200);
- done();
- });
- });
+ done();
+ });
+ });
});
- it('should destroy downward stream on request stream closing', function (done) {
+ it('should destroy downward stream on request stream closing', function (done) {
var tmpFile = '/tmp/test.json';
var output = JSON.stringify({ "x": "aaaaaaaaaaaa" });
Fs.writeFileSync(tmpFile, output);
var testStream = Fs.createReadStream(tmpFile);
- server.start(function () {
+ server.start(function () {
- testStream.pipe(Request.get({ uri: 'http://127.0.0.1:19798/stream/closes', headers: { 'Content-Type': 'application/json' } }, function (err, res) {
+ testStream.pipe(Request.get({ uri: 'http://127.0.0.1:19798/stream/closes', headers: { 'Content-Type': 'application/json' } }, function (err, res) {
expect(res.statusCode).to.equal(200);
- done();
- }));
- });
- });
+ done();
+ }));
+ });
+ });
});
- describe('Cached', function () {
+ describe('Cached', function () {
- it('returns a cached reply', function (done) {
+ it('returns a cached reply', function (done) {
- var cacheHandler = function (request) {
+ var cacheHandler = function (request) {
- request.reply({ status: 'cached' });
+ request.reply({ status: 'cached' });
};
var server = new Hapi.Server({ cache: { engine: 'memory' } });
server.route({ method: 'GET', path: '/cache', config: { handler: cacheHandler, cache: { expiresIn: 5000 } } });
- server.inject({ method: 'GET', url: '/cache' }, function (res1) {
+ server.inject({ method: 'GET', url: '/cache' }, function (res1) {
expect(res1.result).to.exist;
expect(res1.result.status).to.equal('cached');
- server.inject({ method: 'GET', url: '/cache' }, function (res2) {
+ server.inject({ method: 'GET', url: '/cache' }, function (res2) {
expect(res2.readPayload()).to.equal('{"status":"cached"}');
- done();
- });
- });
- });
+ done();
+ });
+ });
+ });
});
- describe('View', function () {
+ describe('View', function () {
var viewPath = __dirname + '/../unit/templates/valid';
var msg = "Hello, World!";
- var handler = function (request) {
+ var handler = function (request) {
- return request.reply.view('test', { message: msg }).send();
+ return request.reply.view('test', { message: msg }).send();
};
- var absoluteHandler = function (request) {
+ var absoluteHandler = function (request) {
- return request.reply.view(viewPath + '/test', { message: msg }).send();
+ return request.reply.view(viewPath + '/test', { message: msg }).send();
};
- var insecureHandler = function (request) {
+ var insecureHandler = function (request) {
- return request.reply.view('../test', { message: msg }).send();
+ return request.reply.view('../test', { message: msg }).send();
};
- var nonexistentHandler = function (request) {
+ var nonexistentHandler = function (request) {
- return request.reply.view('testNope', { message: msg }).send();
+ return request.reply.view('testNope', { message: msg }).send();
};
- var invalidHandler = function (request) {
+ var invalidHandler = function (request) {
- return request.reply.view('badmustache', { message: msg }, { path: viewPath + '/../invalid' }).send();
+ return request.reply.view('badmustache', { message: msg }, { path: viewPath + '/../invalid' }).send();
};
- var layoutConflictHandler = function (request) {
+ var layoutConflictHandler = function (request) {
- return request.reply.view('test', { message: msg, content: 'fail' }).send();
+ return request.reply.view('test', { message: msg, content: 'fail' }).send();
};
- var layoutErrHandler = function (request) {
+ var layoutErrHandler = function (request) {
- return request.reply.view('test', { message: msg }, { path: viewPath + '/../invalid' }).send();
+ return request.reply.view('test', { message: msg }, { path: viewPath + '/../invalid' }).send();
};
- var testMultiHandlerJade = function (request) {
+ var testMultiHandlerJade = function (request) {
- return request.reply.view('testMulti', { message: "Hello World!" }).send();
+ return request.reply.view('testMulti', { message: "Hello World!" }).send();
};
- var testMultiHandlerHB = function (request) {
+ var testMultiHandlerHB = function (request) {
- return request.reply.view('test', { message: "Hello World!" }).send();
+ return request.reply.view('test', { message: "Hello World!" }).send();
};
+ describe('Default', function (done) {
- describe('Default', function (done) {
-
- var server = new Hapi.Server({
- views: {
- path: viewPath
- }
+ var server = new Hapi.Server({
+ views: {
+ path: viewPath
+ }
});
server.route({ method: 'GET', path: '/views', config: { handler: handler } });
server.route({ method: 'GET', path: '/views/abspath', config: { handler: absoluteHandler } });
@@ -1447,623 +1446,623 @@ describe('Response', function () {
server.route({ method: 'GET', path: '/views/nonexistent', config: { handler: nonexistentHandler } });
server.route({ method: 'GET', path: '/views/invalid', config: { handler: invalidHandler } });
- it('returns a compiled Handlebars template reply', function (done) {
+ it('returns a compiled Handlebars template reply', function (done) {
- server.inject({ method: 'GET', url: '/views' }, function (res) {
+ server.inject({ method: 'GET', url: '/views' }, function (res) {
expect(res.result).to.exist;
expect(res.result).to.have.string(msg);
expect(res.statusCode).to.equal(200);
- done();
- });
+ done();
+ });
});
- it('returns an error absolute path given and allowAbsolutePath is false (by default)', function (done) {
+ it('returns an error absolute path given and allowAbsolutePath is false (by default)', function (done) {
- server.inject({ method: 'GET', url: '/views/abspath' }, function (res) {
+ server.inject({ method: 'GET', url: '/views/abspath' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(500);
- done();
- });
+ done();
+ });
});
- it('returns an error if path given includes ../ and allowInsecureAccess is false (by default)', function (done) {
+ it('returns an error if path given includes ../ and allowInsecureAccess is false (by default)', function (done) {
- server.inject({ method: 'GET', url: '/views/insecure' }, function (res) {
+ server.inject({ method: 'GET', url: '/views/insecure' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(500);
- done();
- });
+ done();
+ });
});
- it('returns an error if template does not exist', function (done) {
+ it('returns an error if template does not exist', function (done) {
- server.inject({ method: 'GET', url: '/views/nonexistent' }, function (res) {
+ server.inject({ method: 'GET', url: '/views/nonexistent' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(500);
- done();
- });
+ done();
+ });
});
- it('returns an error if engine.compile throws', function (done) {
+ it('returns an error if engine.compile throws', function (done) {
- server.inject({ method: 'GET', url: '/views/invalid' }, function (res) {
+ server.inject({ method: 'GET', url: '/views/invalid' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(500);
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('Layout', function (done) {
+ describe('Layout', function (done) {
- var layoutServer = new Hapi.Server({
- views: {
+ var layoutServer = new Hapi.Server({
+ views: {
path: viewPath,
- layout: true
- }
+ layout: true
+ }
});
layoutServer.route({ method: 'GET', path: '/layout/conflict', config: { handler: layoutConflictHandler } });
layoutServer.route({ method: 'GET', path: '/layout/abspath', config: { handler: layoutErrHandler } });
- it('returns error on layoutKeyword conflict', function (done) {
+ it('returns error on layoutKeyword conflict', function (done) {
- layoutServer.inject({ method: 'GET', url: '/layout/conflict' }, function (res) {
+ layoutServer.inject({ method: 'GET', url: '/layout/conflict' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(500);
- done();
- })
+ done();
+ })
});
- it('returns an error absolute path given and allowAbsolutePath is false (by default)', function (done) {
+ it('returns an error absolute path given and allowAbsolutePath is false (by default)', function (done) {
- layoutServer.inject({ method: 'GET', url: '/layout/abspath' }, function (res) {
+ layoutServer.inject({ method: 'GET', url: '/layout/abspath' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(500);
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('Engine Support', function () {
+ describe('Engine Support', function () {
- describe('Caching', function () {
+ describe('Caching', function () {
- it('should not throw if local cache disabled', function (done) {
+ it('should not throw if local cache disabled', function (done) {
- var fn = function () {
+ var fn = function () {
- var testServer = new Hapi.Server({
- views: {
+ var testServer = new Hapi.Server({
+ views: {
path: viewPath,
- engines: {
- 'html': {
+ engines: {
+ 'html': {
module: 'handlebars',
- cache: false
- },
- }
- }
+ cache: false
+ },
+ }
+ }
});
testServer.route({ method: 'GET', path: '/handlebars', config: { handler: testMultiHandlerHB } });
- testServer.inject({ method: 'GET', url: '/handlebars' }, function (res) {
+ testServer.inject({ method: 'GET', url: '/handlebars' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(200);
- testServer.inject({ method: 'GET', url: '/handlebars' }, function (res) {
+ testServer.inject({ method: 'GET', url: '/handlebars' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(200);
// done();
- });
- });
+ });
+ });
};
expect(fn).to.not.throw();
- done();
+ done();
});
- it('should use the cache if all caching enabled', function (done) {
+ it('should use the cache if all caching enabled', function (done) {
- var testServer = new Hapi.Server({
- views: {
+ var testServer = new Hapi.Server({
+ views: {
path: viewPath,
cache: {},
- engines: {
- 'html': {
- module: 'handlebars'
- }
- }
- }
+ engines: {
+ 'html': {
+ module: 'handlebars'
+ }
+ }
+ }
});
testServer.route({ method: 'GET', path: '/handlebars', config: { handler: testMultiHandlerHB } });
- testServer.inject({ method: 'GET', url: '/handlebars' }, function (res) {
+ testServer.inject({ method: 'GET', url: '/handlebars' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(200);
- testServer.inject({ method: 'GET', url: '/handlebars' }, function (res) {
+ testServer.inject({ method: 'GET', url: '/handlebars' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(200);
- done();
- });
- });
+ done();
+ });
+ });
});
- it('should not throw if global cache disabled', function (done) {
+ it('should not throw if global cache disabled', function (done) {
- var testServer = new Hapi.Server({
- views: {
+ var testServer = new Hapi.Server({
+ views: {
path: viewPath,
cache: false,
- engine: {
+ engine: {
module: 'handlebars',
extension: 'html',
- slashReplacement: '_',
- }
- }
+ slashReplacement: '_',
+ }
+ }
});
testServer.route({ method: 'GET', path: '/handlebars', config: { handler: testMultiHandlerHB } });
- testServer.inject({ method: 'GET', url: '/handlebars' }, function (res) {
+ testServer.inject({ method: 'GET', url: '/handlebars' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(200);
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('General', function () {
+ describe('General', function () {
- it('should not throw if view map has execute function defined', function (done) {
+ it('should not throw if view map has execute function defined', function (done) {
- var fn = function () {
+ var fn = function () {
- var testServer = new Hapi.Server({
- views: {
+ var testServer = new Hapi.Server({
+ views: {
path: viewPath,
- engines: {
- 'html': {
- module: {
- compile: function (tmpl, options) {
+ engines: {
+ 'html': {
+ module: {
+ compile: function (tmpl, options) {
- return function (ctx) {
+ return function (ctx) {
- return tmpl;
- }
- }
+ return tmpl;
+ }
+ }
},
- map: {
- execute: (function () {
+ map: {
+ execute: (function () {
- return function (engine, compiled, ctx, options, partials) {
+ return function (engine, compiled, ctx, options, partials) {
- return function (ctx, options) {
+ return function (ctx, options) {
- return compiled(ctx, options);
- }
- }
- })
- }
- }
- }
- }
+ return compiled(ctx, options);
+ }
+ }
+ })
+ }
+ }
+ }
+ }
});
testServer.route({ method: 'GET', path: '/exec', config: { handler: testMultiHandlerHB } });
- testServer.inject({ method: 'GET', url: '/exec' }, function (res) {
+ testServer.inject({ method: 'GET', url: '/exec' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(200);
// done();
- });
+ });
};
expect(fn).to.not.throw();
- done();
+ done();
});
- it('should throw if view module not found', function (done) {
+ it('should throw if view module not found', function (done) {
- var fn = function () {
+ var fn = function () {
- var failServer = new Hapi.Server({
- views: {
+ var failServer = new Hapi.Server({
+ views: {
path: viewPath,
- engines: {
+ engines: {
'html': { module: 'handlebars' },
'jade': { module: 'jade' },
- 'hbar': {
+ 'hbar': {
module: 'handlebars',
- map: {
- compile: function (engine) { return engine.compile; }
- }
+ map: {
+ compile: function (engine) { return engine.compile; }
+ }
},
- 'err': {
- module: 'hapi-module-that-does-not-exist'
- }
- }
- }
- });
+ 'err': {
+ module: 'hapi-module-that-does-not-exist'
+ }
+ }
+ }
+ });
};
expect(fn).to.throw();
- done();
+ done();
});
- it('should work if view engine module is a pre-required module', function (done) {
+ it('should work if view engine module is a pre-required module', function (done) {
- var options = {
- views: {
+ var options = {
+ views: {
path: viewPath,
- engines: {
- 'test': {
- module: require('jade')
- }
- }
- }
+ engines: {
+ 'test': {
+ module: require('jade')
+ }
+ }
+ }
};
- var fn = function () {
+ var fn = function () {
- var passServer = new Hapi.Server(options);
+ var passServer = new Hapi.Server(options);
};
expect(fn).to.not.throw();
- done();
- });
+ done();
+ });
});
- describe('Single', function () {
+ describe('Single', function () {
- var server = new Hapi.Server({
- views: {
+ var server = new Hapi.Server({
+ views: {
path: viewPath,
- engine: {
+ engine: {
module: 'handlebars',
extension: 'html',
- slashReplacement: '_',
- }
- }
+ slashReplacement: '_',
+ }
+ }
});
server.route({ method: 'GET', path: '/handlebars', config: { handler: testMultiHandlerHB } });
- it('should render handlebars template', function (done) {
+ it('should render handlebars template', function (done) {
- server.inject({ method: 'GET', url: '/handlebars' }, function (res) {
+ server.inject({ method: 'GET', url: '/handlebars' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(200);
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('Multiple', function () {
+ describe('Multiple', function () {
- var server = new Hapi.Server({
- views: {
+ var server = new Hapi.Server({
+ views: {
path: viewPath,
- engines: {
+ engines: {
'html': { module: 'handlebars' },
'jade': { module: 'jade' },
- 'hbar': {
+ 'hbar': {
module: 'handlebars',
- map: {
- compile: function (engine) { return engine.compile; }
- }
- },
- }
- }
+ map: {
+ compile: function (engine) { return engine.compile; }
+ }
+ },
+ }
+ }
});
server.route({ method: 'GET', path: '/jade', config: { handler: testMultiHandlerJade } });
server.route({ method: 'GET', path: '/handlebars', config: { handler: testMultiHandlerHB } });
- it('should render jade template', function (done) {
+ it('should render jade template', function (done) {
- server.inject({ method: 'GET', url: '/jade' }, function (res) {
+ server.inject({ method: 'GET', url: '/jade' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(200);
- done();
- });
+ done();
+ });
});
- it('should render handlebars template', function (done) {
+ it('should render handlebars template', function (done) {
- server.inject({ method: 'GET', url: '/handlebars' }, function (res) {
+ server.inject({ method: 'GET', url: '/handlebars' }, function (res) {
expect(res.result).to.exist;
expect(res.statusCode).to.equal(200);
- done();
- });
- });
- });
- });
+ done();
+ });
+ });
+ });
+ });
});
- describe('Redirection', function () {
+ describe('Redirection', function () {
- var handler = function (request) {
+ var handler = function (request) {
- if (!request.query.x) {
- return request.reply.redirect('example').send();
+ if (!request.query.x) {
+ return request.reply.redirect('example').send();
}
- if (request.query.x === 'verbose') {
- return request.reply.redirect().uri('examplex').message('We moved!').send();
+ if (request.query.x === 'verbose') {
+ return request.reply.redirect().uri('examplex').message('We moved!').send();
}
- if (request.query.x === '302') {
- return request.reply.redirect('example').temporary().rewritable().send();
+ if (request.query.x === '302') {
+ return request.reply.redirect('example').temporary().rewritable().send();
}
- if (request.query.x === '307') {
- return request.reply.redirect('example').temporary().rewritable(false).send();
+ if (request.query.x === '307') {
+ return request.reply.redirect('example').temporary().rewritable(false).send();
}
- if (request.query.x === '301') {
- return request.reply.redirect('example').permanent().rewritable().send();
+ if (request.query.x === '301') {
+ return request.reply.redirect('example').permanent().rewritable().send();
}
- if (request.query.x === '308') {
- return request.reply.redirect('example').permanent().rewritable(false).send();
+ if (request.query.x === '308') {
+ return request.reply.redirect('example').permanent().rewritable(false).send();
}
- if (request.query.x === '302f') {
- return request.reply.redirect('example').rewritable().temporary().send();
+ if (request.query.x === '302f') {
+ return request.reply.redirect('example').rewritable().temporary().send();
}
- if (request.query.x === '307f') {
- return request.reply.redirect('example').rewritable(false).temporary().send();
+ if (request.query.x === '307f') {
+ return request.reply.redirect('example').rewritable(false).temporary().send();
}
- if (request.query.x === '301f') {
- return request.reply.redirect('example').rewritable().permanent().send();
+ if (request.query.x === '301f') {
+ return request.reply.redirect('example').rewritable().permanent().send();
}
- if (request.query.x === '308f') {
- return request.reply.redirect('example').rewritable(false).permanent().send();
- }
+ if (request.query.x === '308f') {
+ return request.reply.redirect('example').rewritable(false).permanent().send();
+ }
};
var server = new Hapi.Server(0);
server.route({ method: 'GET', path: '/redirect', config: { handler: handler } });
- before(function (done) {
+ before(function (done) {
- server.start(done);
+ server.start(done);
});
- it('returns a redirection reply', function (done) {
+ it('returns a redirection reply', function (done) {
- server.inject({ method: 'GET', url: '/redirect' }, function (res) {
+ server.inject({ method: 'GET', url: '/redirect' }, function (res) {
expect(res.result).to.exist;
expect(res.result).to.equal('You are being redirected...');
expect(res.headers['Location']).to.equal(server.settings.uri + '/example');
expect(res.statusCode).to.equal(302);
- done();
- });
+ done();
+ });
});
- it('returns a redirection reply using verbose call', function (done) {
+ it('returns a redirection reply using verbose call', function (done) {
- server.inject({ method: 'GET', url: '/redirect?x=verbose' }, function (res) {
+ server.inject({ method: 'GET', url: '/redirect?x=verbose' }, function (res) {
expect(res.result).to.exist;
expect(res.result).to.equal('We moved!');
expect(res.headers['Location']).to.equal(server.settings.uri + '/examplex');
expect(res.statusCode).to.equal(302);
- done();
- });
+ done();
+ });
});
- it('returns a 301 redirection reply', function (done) {
+ it('returns a 301 redirection reply', function (done) {
- server.inject({ method: 'GET', url: '/redirect?x=301' }, function (res) {
+ server.inject({ method: 'GET', url: '/redirect?x=301' }, function (res) {
expect(res.statusCode).to.equal(301);
- done();
- });
+ done();
+ });
});
- it('returns a 302 redirection reply', function (done) {
+ it('returns a 302 redirection reply', function (done) {
- server.inject({ method: 'GET', url: '/redirect?x=302' }, function (res) {
+ server.inject({ method: 'GET', url: '/redirect?x=302' }, function (res) {
expect(res.statusCode).to.equal(302);
- done();
- });
+ done();
+ });
});
- it('returns a 307 redirection reply', function (done) {
+ it('returns a 307 redirection reply', function (done) {
- server.inject({ method: 'GET', url: '/redirect?x=307' }, function (res) {
+ server.inject({ method: 'GET', url: '/redirect?x=307' }, function (res) {
expect(res.statusCode).to.equal(307);
- done();
- });
+ done();
+ });
});
- it('returns a 308 redirection reply', function (done) {
+ it('returns a 308 redirection reply', function (done) {
- server.inject({ method: 'GET', url: '/redirect?x=308' }, function (res) {
+ server.inject({ method: 'GET', url: '/redirect?x=308' }, function (res) {
expect(res.statusCode).to.equal(308);
- done();
- });
+ done();
+ });
});
- it('returns a 301 redirection reply (reveresed methods)', function (done) {
+ it('returns a 301 redirection reply (reveresed methods)', function (done) {
- server.inject({ method: 'GET', url: '/redirect?x=301f' }, function (res) {
+ server.inject({ method: 'GET', url: '/redirect?x=301f' }, function (res) {
expect(res.statusCode).to.equal(301);
- done();
- });
+ done();
+ });
});
- it('returns a 302 redirection reply (reveresed methods)', function (done) {
+ it('returns a 302 redirection reply (reveresed methods)', function (done) {
- server.inject({ method: 'GET', url: '/redirect?x=302f' }, function (res) {
+ server.inject({ method: 'GET', url: '/redirect?x=302f' }, function (res) {
expect(res.statusCode).to.equal(302);
- done();
- });
+ done();
+ });
});
- it('returns a 307 redirection reply (reveresed methods)', function (done) {
+ it('returns a 307 redirection reply (reveresed methods)', function (done) {
- server.inject({ method: 'GET', url: '/redirect?x=307f' }, function (res) {
+ server.inject({ method: 'GET', url: '/redirect?x=307f' }, function (res) {
expect(res.statusCode).to.equal(307);
- done();
- });
+ done();
+ });
});
- it('returns a 308 redirection reply (reveresed methods)', function (done) {
+ it('returns a 308 redirection reply (reveresed methods)', function (done) {
- server.inject({ method: 'GET', url: '/redirect?x=308f' }, function (res) {
+ server.inject({ method: 'GET', url: '/redirect?x=308f' }, function (res) {
expect(res.statusCode).to.equal(308);
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('External', function () {
+ describe('External', function () {
- it('returns a reply', function (done) {
+ it('returns a reply', function (done) {
- var handler = function () {
+ var handler = function () {
this.raw.res.end();
- this.reply.close();
+ this.reply.close();
};
var server = new Hapi.Server({ cache: { engine: 'memory' } });
server.route({ method: 'GET', path: '/throw', config: { handler: handler, cache: { mode: 'server', expiresIn: 9999 } } });
server.route({ method: 'GET', path: '/null', config: { handler: handler } });
- server.inject({ method: 'GET', url: '/null' }, function (res) {
+ server.inject({ method: 'GET', url: '/null' }, function (res) {
expect(res.readPayload()).to.equal('0\r\n\r\n');
- expect(function () {
+ expect(function () {
- server.inject({ method: 'GET', url: '/throw' }, function (res) { });
+ server.inject({ method: 'GET', url: '/throw' }, function (res) { });
}).to.throw();
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('Extension', function () {
+ describe('Extension', function () {
- it('returns a reply using custom response without _prepare', function (done) {
+ it('returns a reply using custom response without _prepare', function (done) {
- var handler = function () {
+ var handler = function () {
- var custom = {
+ var custom = {
variety: 'x-custom',
varieties: { 'x-custom': true },
- _transmit: function (request, callback) {
+ _transmit: function (request, callback) {
request.raw.res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': 11 });
- request.raw.res.end('Hello World');
- }
+ request.raw.res.end('Hello World');
+ }
};
- this.reply(custom);
+ this.reply(custom);
};
var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', config: { handler: handler } });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.readPayload()).to.equal('Hello World');
- done();
- });
+ done();
+ });
});
- it('returns an internal error on error response loop', function (done) {
+ it('returns an internal error on error response loop', function (done) {
- var handler = function () {
+ var handler = function () {
- var custom = {
+ var custom = {
variety: 'x-custom',
varieties: { 'x-custom': true },
- _prepare: function (request, callback) {
+ _prepare: function (request, callback) {
- callback(Hapi.error.badRequest());
+ callback(Hapi.error.badRequest());
},
- _transmit: function () { }
+ _transmit: function () { }
};
this.setState('bad', {});
- this.reply(custom);
+ this.reply(custom);
};
var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', config: { handler: handler } });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.result.code).to.equal(500);
- done();
- });
+ done();
+ });
});
- it('returns an error on infinite _prepare loop', function (done) {
+ it('returns an error on infinite _prepare loop', function (done) {
- var handler = function () {
+ var handler = function () {
- var custom = {
+ var custom = {
variety: 'x-custom',
varieties: { 'x-custom': true },
- _prepare: function (request, callback) {
+ _prepare: function (request, callback) {
- callback(custom);
- }
+ callback(custom);
+ }
};
- this.reply(custom);
+ this.reply(custom);
};
var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', config: { handler: handler } });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.result.code).to.equal(500);
- done();
- });
- });
+ done();
+ });
+ });
});
- describe('#_respond', function () {
+ describe('#_respond', function () {
- it('returns an error reply on invalid Response._respond', function (done) {
+ it('returns an error reply on invalid Response._respond', function (done) {
- var handler = function (request) {
+ var handler = function (request) {
- Hapi.Response._respond(null, request, function () { });
+ Hapi.Response._respond(null, request, function () { });
};
var server = new Hapi.Server();
server.route({ method: 'GET', path: '/', handler: handler });
- server.inject({ method: 'GET', url: '/' }, function (res) {
+ server.inject({ method: 'GET', url: '/' }, function (res) {
expect(res.statusCode).to.equal(500);
expect(res.result).to.exist;
expect(res.result.message).to.equal('An internal server error occurred');
- done();
- });
- });
- });
+ done();
+ });
+ });
+ });
});