Skip to content

Commit

Permalink
Relative paths
Browse files Browse the repository at this point in the history
  • Loading branch information
Eran Hammer committed Feb 28, 2013
1 parent 836890a commit a0dedd7
Show file tree
Hide file tree
Showing 17 changed files with 1,123 additions and 1,036 deletions.
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
<img src="https://raw.github.com/olivierlacan/shields/master/coveralls/coveralls_100.png" />
Expand Down Expand Up @@ -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
<html>
<head><title>Hello Static</title></head>
<body>
Hello Static
</body>
<head><title>Hello Static</title></head>
<body>
Hello Static
</body>
</html>
```

Expand All @@ -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
<html>
<head><title>{{greeting}}</title></head>
<body>
{{greeting}}
</body>
<head><title>{{greeting}}</title></head>
<body>
{{greeting}}
</body>
</html>
```

Expand All @@ -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();
}
};
Expand Down
14 changes: 12 additions & 2 deletions docs/Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -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()'_).

Expand Down Expand Up @@ -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.

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
90 changes: 49 additions & 41 deletions lib/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand All @@ -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');
Expand All @@ -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) {
Expand All @@ -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]);
};

Loading

0 comments on commit a0dedd7

Please sign in to comment.