Skip to content

Commit

Permalink
Merge pull request #27 from doublesharp/master
Browse files Browse the repository at this point in the history
Optionally respond with CORS headers
  • Loading branch information
ericmdantas authored Jan 28, 2017
2 parents 71cd9c7 + f7a8da9 commit 8f30729
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 6 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Oh, do you want some specific stuff? Checkout the available <a href="#options">o
--port, --p change port
--host, --h change the host name
--secure, --s use https/wss
--cors, --c respond to requests with CORS headers, use true or object to override defaults
--quiet, --q no logging whatsoever
--noBrowser, --nb won't open the browser automagically
--only, --o will only watch for changes in the given path/glob/regex/array
Expand All @@ -87,6 +88,11 @@ All the <a href="#options">options</a> being used on the `CLI` can be added to t
{
"port": 9999,
"quiet": true,
"cors": {
"headers": "Content-Type, Custom-Header",
"methods": "GET, OPTIONS",
"credentials": false
},
"pathIndex": "src/",
"only": ["src/**/*"],
"proxy": true,
Expand Down Expand Up @@ -116,6 +122,7 @@ new Server({quiet: true}).start();
--port is 1307
--host is 127.0.0.1
--secure is false
--cors is false
--quiet is false
--only is ".", which means it'll watch everything
--ignore is ^(.git|node_modules|bower_components|jspm_packages|test|typings|coverage|unit_coverage)
Expand Down
1 change: 1 addition & 0 deletions lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module.exports = {
noBrowser: false,
host: '127.0.0.1',
secure: false,
cors: false,
static: [],
port: 1307,
pathIndex: '',
Expand Down
37 changes: 33 additions & 4 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ module.exports = class Server extends EventEmitter {
{
short: 'st',
long: 'static'
},
{
short: 'c',
long: 'cors'
}
];

Expand Down Expand Up @@ -204,6 +208,8 @@ module.exports = class Server extends EventEmitter {
threshold: '1kb'
}));

this._initCors();

this.opts.static.forEach((p) => {
this._app.use(express.static(p, {
index: false
Expand All @@ -215,22 +221,45 @@ module.exports = class Server extends EventEmitter {
this._app.get(/.+/, (req, res) => this._sendIndex(req, res));
}

_initCors() {
if (!!this.opts.cors) {
this._app.use(this._cors());
}
}

_cors() {
const corsOptions = Object.assign({
methods: 'GET, POST, OPTIONS, PUT, PATCH, DELETE',
headers: 'Authorization,X-Requested-With,Content-Type',
credentials: true,
}, this.opts.cors || {});

return function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', req.headers.origin || '*');
res.setHeader('Access-Control-Allow-Methods', corsOptions.methods);
res.setHeader('Access-Control-Allow-Headers', corsOptions.headers);
res.setHeader('Access-Control-Allow-Credentials', corsOptions.credentials);

return req.method === 'OPTIONS' ? res.status(200).end() : next();
}
}

_initProxy() {
if (this.opts.proxy) {
this._app.all(this.opts.proxyWhen, (req, res) => {
this.emit('proxy', {req: req});
this._proxyServer.web(req, res);
})
});

this._proxyServer.on('proxyReq', (proxyReq, req) => {
req._proxyReq = proxyReq;
})
});

this._proxyServer.on('error', (err, req, res) => {
this._proxyServer.on('error', (err, req, res) => {
if (req.socket.destroyed && err.code === 'ECONNRESET') {
req._proxyReq.abort();
}
})
});
}
}

Expand Down
Empty file added test/index.html
Empty file.
1 change: 1 addition & 0 deletions test/options_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ describe('options', () => {
expect(options.pathIndex).to.equal('');
expect(options.noBrowser).to.be.false;
expect(options.secure).to.be.false;
expect(options.cors).to.be.false;
expect(options.static).to.deep.equal([]);
expect(options.quiet).to.be.false;
expect(options.proxy).to.be.false;
Expand Down
19 changes: 17 additions & 2 deletions test/server_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe('server', () => {
expect(_server.opts.host).to.equal('127.0.0.1');
expect(_server.opts.port).to.equal(1307);
expect(_server.opts.secure).to.equal(false);
expect(_server.opts.cors).to.be.false;
expect(_server.opts.quiet).to.be.false;
expect(_server.opts.pathIndex).to.equal('');
expect(_server.opts.noBrowser).to.equal(false);
Expand Down Expand Up @@ -560,14 +561,28 @@ describe('server', () => {
});

describe('options', function() {
it('should open the browser', () => {
let _server = new Server();
it('should open the browser and use CORS with custom access-control-allow-headers', (done) => {
let _server = new Server({
cors: {
headers: 'test-header',
},
quiet: true,
pathIndex: 'test/'
});

let _openStub = sinon.stub(_server, '_open', () => {});

_server.start();

http.get(`http://${_server.opts.host}:${_server.opts.port}/`, function(res) {
expect(res.headers['access-control-allow-origin']).to.not.be.undefined;
expect(res.headers['access-control-allow-headers']).to.equal('test-header');
expect(res.headers['access-control-allow-credentials']).to.equal('true');
return done();
})

expect(_server._open).to.have.been.called;
expect(_server._cors).to.have.been.called;

_openStub.restore();
});
Expand Down

0 comments on commit 8f30729

Please sign in to comment.