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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,22 @@ let server = new FastBootAppServer({
server.start();
```

## Pre and Post FastBoot middleware hooks

If you need something less than a custom server and just want to run some middleware
before or after FastBoot runs, the server provides hooks for you to do so:

```js
// Custom Middlewares
function modifyRequest(req, res, next) { /* do pre-fastboot stuff to `req` */ };
function handleErrors(err, req, res, next) { /* do error recovery stuff */ };

const server = FastBootAppServer({
beforeMiddleware: function (app) { app.use(modifyRequest); },
afterMiddleware: function (app) { app.use(handleErrors); }
})
```

## Downloaders

You can point the app server at a static path that you manage, but that
Expand Down Expand Up @@ -191,7 +207,7 @@ following interface:

#### `subscribe(notify)`

The `subscribe()` method ony our notifier is passed a `notify` function.
The `subscribe()` method on your notifier is passed a `notify` function.
If you detect that a new version of your app has been deployed (whether
via polling or a push notification), call this function to trigger a
reload.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"compression": "^1.6.2",
"express": "^4.13.3",
"fastboot": "^1.0.0-rc.0",
"fastboot-express-middleware": "^1.0.0-rc.3",
"fastboot-express-middleware": "^1.0.0-rc.4",
"fs-promise": "^0.3.1"
},
"devDependencies": {
Expand Down
21 changes: 15 additions & 6 deletions src/express-http-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
const express = require('express');
const basicAuth = require('./basic-auth');

function noop() {}

class ExpressHTTPServer {
constructor(options) {
options = options || {};
Expand All @@ -13,18 +15,23 @@ class ExpressHTTPServer {
this.password = options.password;
this.cache = options.cache;
this.gzip = options.gzip || false;
this.beforeMiddleware = options.beforeMiddleware || noop;
this.afterMiddleware = options.afterMiddleware || noop;

this.app = express();
if (options.gzip) {
this.app.use(require('compression')());
}
}

serve(middleware) {
serve(fastbootMiddleware) {
let app = this.app;
let username = this.username;
let password = this.password;

this.beforeMiddleware(app);

if (this.gzip) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Had to move this code to get the execution order right.

this.app.use(require('compression')());
}

if (username !== undefined || password !== undefined) {
this.ui.writeLine(`adding basic auth; username=${username}; password=${password}`);
app.use(basicAuth(username, password));
Expand All @@ -35,14 +42,16 @@ class ExpressHTTPServer {
}

if (this.distPath) {
app.get('/', middleware);
app.get('/', fastbootMiddleware);
app.use(express.static(this.distPath));
app.get('/assets/*', function(req, res) {
res.sendStatus(404);
});
}

app.get('/*', middleware);
app.get('/*', fastbootMiddleware);

this.afterMiddleware(app);

return new Promise(resolve => {
let listener = app.listen(process.env.PORT || 3000, () => {
Expand Down
8 changes: 6 additions & 2 deletions src/fastboot-app-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ class FastBootAppServer {
this.notifier = options.notifier;
this.cache = options.cache;
this.ui = options.ui;
this.gzip = options.gzip || false;
this.gzip = options.gzip;
this.httpServer = options.httpServer;
this.beforeMiddleware = options.beforeMiddleware;
this.afterMiddleware = options.afterMiddleware;

if (!this.ui) {
let UI = require('./ui');
Expand All @@ -31,7 +33,9 @@ class FastBootAppServer {
distPath: this.distPath || process.env.FASTBOOT_DIST_PATH,
cache: this.cache,
gzip: this.gzip,
httpServer: this.httpServer
httpServer: this.httpServer,
beforeMiddleware: this.beforeMiddleware,
afterMiddleware: this.afterMiddleware
});

this.worker.start();
Expand Down
9 changes: 6 additions & 3 deletions src/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@ class Worker {
this.httpServer = options.httpServer;
this.ui = options.ui;
this.cache = options.cache;
this.gzip = options.gzip || false;
this.gzip = options.gzip;
this.beforeMiddleware = options.beforeMiddleware;
this.afterMiddleware = options.afterMiddleware;

if (!this.httpServer) {
this.httpServer = new ExpressHTTPServer({
ui: this.ui,
distPath: this.distPath,
cache: this.cache,
gzip: this.gzip
gzip: this.gzip,
beforeMiddleware: this.beforeMiddleware,
afterMiddleware: this.afterMiddleware,
});
}

Expand Down Expand Up @@ -58,7 +62,6 @@ class Worker {
buildMiddleware() {
this.fastboot = new FastBoot({
distPath: this.distPath,
resilient: true
});

return fastbootMiddleware({
Expand Down
19 changes: 19 additions & 0 deletions test/app-server-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,25 @@ describe("FastBootAppServer", function() {
});
});

it("executes beforeMiddleware", function() {
return runServer('before-middleware-server')
.then(() => request('http://localhost:3000'))
.then(response => {
expect(response.statusCode).to.equal(418);
expect(response.headers['x-test-header']).to.equal('testing');
expect(response.body).to.equal(JSON.stringify({ send: 'json back'}));
});
});

it("executes afterMiddleware when there is an error", function() {
return runServer('after-middleware-server')
.then(() => request('http://localhost:3000'))
.then(response => {
expect(response.body).to.not.match(/error/);
expect(response.headers['x-test-header']).to.equal('testing');
})
});

});

function runServer(name) {
Expand Down
20 changes: 20 additions & 0 deletions test/fixtures/after-middleware-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';

var path = require('path');
var alchemistRequire = require('broccoli-module-alchemist/require');
var FastBootAppServer = alchemistRequire('fastboot-app-server');

function setXTestHeader(err, req, res, next) {
res.set('x-test-header', 'testing')
next();
}

var server = new FastBootAppServer({
distPath: path.resolve(__dirname, './broken-app'),
afterMiddleware: function (app) {
app.use(setXTestHeader);
},
resilient: true,
});

server.start();
31 changes: 31 additions & 0 deletions test/fixtures/before-middleware-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict';

var path = require('path');
var alchemistRequire = require('broccoli-module-alchemist/require');
var FastBootAppServer = alchemistRequire('fastboot-app-server');

function setStatusCode418(req, res, next) {
res.status(418);
next();
}

function setXTestHeader(req, res, next) {
res.set('X-Test-Header', 'testing')
next();
}

function sendJsonAndTerminate(req, res, next) {
res.json({ send: 'json back' });
res.send();
}

var server = new FastBootAppServer({
distPath: path.resolve(__dirname, './basic-app'),
beforeMiddleware: function (app) {
app.use(setStatusCode418);
app.use(setXTestHeader);
app.use(sendJsonAndTerminate);
}
});

server.start();
Loading