Skip to content

Add support for credentials requests #434

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ Using `npx` you can run the script without installing it first:

`--cors` Enable CORS via the `Access-Control-Allow-Origin` header

`--credentials` Cookie credentials can be transferred as part of a CORS request (enables `--cors` automatically)

`-o [path]` Open browser window after starting the server. Optionally provide a URL path to open. e.g.: -o /other/dir/

`-c` Set cache time (in seconds) for cache-control max-age header, e.g. `-c10` for 10 seconds (defaults to `3600`). To disable caching, use `-c-1`.
Expand Down
7 changes: 7 additions & 0 deletions bin/http-server
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ var colors = require('colors/safe'),
argv = require('optimist')
.boolean('cors')
.boolean('log-ip')
.boolean('credentials')
.argv;

var ifaces = os.networkInterfaces();
Expand All @@ -30,6 +31,8 @@ if (argv.h || argv.help) {
' -s --silent Suppress log messages from output',
' --cors[=headers] Enable CORS via the "Access-Control-Allow-Origin" header',
' Optionally provide CORS headers list separated by commas',
' --credentials Cookie credentials can be transferred as part of a CORS request',
' Enables --cors automatically',
Comment on lines +34 to +35
Copy link
Member

Choose a reason for hiding this comment

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

I'm concerned that the name of this switch is too general for its use case, how would you feel about --cookie-credentials or shorten to --cookie-creds or something like that?

' -o [path] Open browser window after starting the server.',
' Optionally provide a URL path to open the browser window to.',
' -c Cache time (max-age) in seconds [3600], e.g. -c10 for 10 seconds.',
Expand Down Expand Up @@ -129,6 +132,10 @@ function listen(port) {
}
}

if (argv.credentials) {
options.credentials = true;
}

if (ssl) {
options.https = {
cert: argv.C || argv.cert || 'cert.pem',
Expand Down
14 changes: 11 additions & 3 deletions lib/http-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,24 @@ function HttpServer(options) {
});
}

if (options.cors) {
if (options.cors || options.credentials) {
this.headers['Access-Control-Allow-Origin'] = '*';
this.headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Range';
if (options.corsHeaders) {
options.corsHeaders.split(/\s*,\s*/)
.forEach(function (h) { this.headers['Access-Control-Allow-Headers'] += ', ' + h; }, this);
}
before.push(corser.create(options.corsHeaders ? {

var corserOptions = options.corsHeaders ? {
requestHeaders: this.headers['Access-Control-Allow-Headers'].split(/\s*,\s*/)
} : null));
} : {};

if (options.credentials) {
corserOptions.supportsCredentials = true;
this.headers['Access-Control-Allow-Credentials'] = 'true';
}

before.push(corser.create(corserOptions));
}

if (options.robots) {
Expand Down
37 changes: 37 additions & 0 deletions test/http-server-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,43 @@ vows.describe('http-server').addBatch({
},
'response Access-Control-Allow-Headers should contain X-Test': function (err, res) {
assert.ok(res.headers['access-control-allow-headers'].split(/\s*,\s*/g).indexOf('X-Test') >= 0, 204);
},
'response Access-Control-Allow-Credentials should not be presented': function (err, res) {
assert.equal(res.headers['access-control-allow-credentials'], undefined);
}
}
},
'When credentials is enabled': {
topic: function () {
var server = httpServer.createServer({
root: root,
credentials: true,
corsHeaders: 'X-Test'
});
server.listen(8085);
this.callback(null, server);
},
'and given OPTIONS request': {
topic: function () {
request({
method: 'OPTIONS',
uri: 'http://127.0.0.1:8085/',
headers: {
'Access-Control-Request-Method': 'GET',
Origin: 'http://example.com',
'Access-Control-Request-Headers': 'Foobar',
Cookie: 'cookie'
}
}, this.callback);
},
'status code should be 204': function (err, res) {
assert.equal(res.statusCode, 204);
},
'response Access-Control-Allow-Headers should contain X-Test': function (err, res) {
assert.ok(res.headers['access-control-allow-headers'].split(/\s*,\s*/g).indexOf('X-Test') >= 0, 204);
},
'response Access-Control-Allow-Credentials should be true': function (err, res) {
assert.equal(res.headers['access-control-allow-credentials'], 'true');
}
}
},
Expand Down