Skip to content

Commit

Permalink
Merge pull request #924 from spumko/issue/922
Browse files Browse the repository at this point in the history
Issue/922
  • Loading branch information
geek committed Jun 12, 2013
2 parents 01bec39 + 1aaf7b4 commit 3f74226
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 12 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ infrastructure. The framework supports a powerful plugin architecture for pain-f

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

Current version: **1.7.x**
Current version: **1.8.x**

Node version: **0.10** required

Expand Down
4 changes: 3 additions & 1 deletion docs/Reference.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# 1.7.x API Reference
# 1.8.x API Reference

- [`Hapi.Server`](#hapiserver)
- [`new Server([host], [port], [options])`](#new-serverhost-port-options)
Expand Down Expand Up @@ -357,6 +357,8 @@ The following options are available when adding a route:
- `listing` - optional boolean, determines if directory listing is generated when a directory is requested without an index document.
Defaults to `false`.
- `showHidden` - optional boolean, determines if hidden files will be shown and served. Defaults to `false`.
- `redirectToSlash` - optional boolean, determines if requests for a directory without a trailing slash are redirected to the same path with
the missing slash. Useful for ensuring relative links inside the response are resolved correctly.
<p></p>
- `proxy` - generates a reverse proxy handler with the following options:
- `host` - the upstream service host to proxy requests to. The same path on the client request will be used as the path on the host.
Expand Down
8 changes: 4 additions & 4 deletions examples/directory/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ internals.serveImages = function (request) {

internals.main = function () {

var http = new Hapi.Server(8080);
var server = new Hapi.Server(8000, { files: { relativeTo: 'routes' } });

http.route([
server.route([
{ method: 'GET', path: '/img/{path}', handler: { directory: { path: internals.serveImages } } },
{ method: 'GET', path: '/files/{path*}', handler: { directory: { path: '../../', listing: true } } },
{ method: 'GET', path: '/files/{path*}', handler: { directory: { path: '../../', listing: true, redirectToSlash: true } } },
{ method: 'GET', path: '/{path?}', handler: { directory: { path: './' } } }
]);

http.start();
server.start();
};


Expand Down
3 changes: 2 additions & 1 deletion lib/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ exports.directoryHandler = function (route, options) {
selection: selection,
index: settings.index,
listing: settings.listing,
showHidden: settings.showHidden
showHidden: settings.showHidden,
redirectToSlash: settings.redirectToSlash
});

return request.reply(response);
Expand Down
16 changes: 12 additions & 4 deletions lib/response/directory.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var Fs = require('fs');
var Path = require('path');
var Async = require('async');
var Cacheable = require('./cacheable');
var Redirection = require('./redirection');
var Boom = require('boom');
var File = require('./file');
var Utils = require('../utils');
Expand Down Expand Up @@ -31,6 +32,9 @@ exports = module.exports = internals.Directory = function (paths, options) {
this._index = options.index === false ? false : true; // Defaults to true
this._listing = !!options.listing; // Defaults to false
this._showHidden = !!options.showHidden; // Defaults to false
this._redirectToSlash = !!options.redirectToSlash; // Defaults to false

this._hasTrailingSlash = this._resource && (this._resource[this._resource.length - 1] === '/');
};

Utils.inherits(internals.Directory, Cacheable);
Expand Down Expand Up @@ -99,6 +103,12 @@ internals.Directory.prototype._preparePath = function (path, request, callback)
return callback(Boom.forbidden());
}

if (self._redirectToSlash &&
!self._hasTrailingSlash) {

return callback(new Redirection(self._resource + '/'));
}

if (!self._index) {
return self._generateListing(path, request, callback);
}
Expand Down Expand Up @@ -141,19 +151,17 @@ internals.Directory.prototype._generateListing = function (path, request, callba
return callback(Boom.internal('Error accessing directory'));
}

var separator = '';
var display = Utils.escapeHtml(self._resource);
var html = '<html><head><title>' + display + '</title></head><body><h1>Directory: ' + display + '</h1><ul>';

if (self._selection) {
separator = '/';
var parent = self._resource.substring(0, self._resource.lastIndexOf('/')) || '/';
var parent = self._resource.substring(0, self._resource.lastIndexOf('/', self._resource.length - (self._hasTrailingSlash ? 2 : 1))) + '/';
html += '<li><a href="' + internals.pathEncode(parent) + '">Parent Directory</a></li>';
}

for (var i = 0, il = files.length; i < il; ++i) {
if (!self._hideFile(files[i])) {
html += '<li><a href="' + internals.pathEncode(self._resource + separator + files[i]) + '">' + Utils.escapeHtml(files[i]) + '</a></li>';
html += '<li><a href="' + internals.pathEncode(self._resource + (self._selection && !self._hasTrailingSlash ? '/' : '') + files[i]) + '">' + Utils.escapeHtml(files[i]) + '</a></li>';
}
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "hapi",
"description": "HTTP Server framework",
"homepage": "http://hapijs.com",
"version": "1.7.3",
"version": "1.8.0",
"author": "Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)",
"contributors": [
{
Expand Down
11 changes: 11 additions & 0 deletions test/integration/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,7 @@ describe('Response', function () {
server.route({ method: 'GET', path: '/{path*}', handler: { directory: { path: './', index: true, listing: true } } });
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 } } });
server.route({ method: 'GET', path: '/redirect/{path*}', handler: { directory: { path: './', index: true, listing: true, redirectToSlash: true } } });

it('returns a 403 when no index exists and listing is disabled', function (done) {

Expand Down Expand Up @@ -940,6 +941,16 @@ describe('Response', function () {
done();
});
});

it('redirects to the same path with / appended if asking for a directory', function (done) {

server.inject('http://example.com/redirect/directory/subdir', function (res) {

expect(res.statusCode).to.equal(302);
expect(res.headers.location).to.equal('http://example.com/redirect/directory/subdir/');
done();
});
});
});

describe('Stream', function () {
Expand Down
5 changes: 5 additions & 0 deletions test/integration/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,18 @@ describe('Server', function () {
});
});
});

it('removes connection event listeners after it stops', function (done) {

var server = Hapi.createServer(0);
server.start(function () {

server.stop(function () {

server.start(function () {

server.stop(function () {

expect(server.listeners('connection').length).to.be.eql(0);
done();
});
Expand Down

0 comments on commit 3f74226

Please sign in to comment.