Skip to content
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

feature: introduces CSP support #136

Open
wants to merge 1 commit 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/sirv-cli/bin.js
Expand Up @@ -6,7 +6,7 @@ const pkg = require('./package');
sade('sirv [dir]')
.version(pkg.version)
.describe('Run a static file server')
.example('build --cors --port 8888')
.example('build --cors --csp "default-src example.com" --port 8888')
.example('public --quiet --etag --maxage 31536000 --immutable')
.example('public --http2 --key priv.pem --cert cert.pem')
.example('public -qeim 31536000')
Expand All @@ -15,6 +15,7 @@ sade('sirv [dir]')
.option('-D, --dev', 'Enable "dev" mode')
.option('-e, --etag', 'Enable "ETag" header')
.option('-d, --dotfiles', 'Enable dotfile asset requests')
.option('-C, --csp', 'Set Content-Security-Policy headers')
.option('-c, --cors', 'Enable "CORS" headers to allow any origin requestor')
.option('-G, --gzip', 'Send precompiled "*.gz" files when "gzip" is supported', true)
.option('-B, --brotli', 'Send precompiled "*.br" files when "brotli" is supported', true)
Expand All @@ -39,6 +40,7 @@ sade('sirv [dir]')
immutable: false,
http2: false,
cors: false,
csp: false,
logs: true,
}
});
6 changes: 6 additions & 0 deletions packages/sirv-cli/index.js
Expand Up @@ -41,6 +41,12 @@ module.exports = function (dir, opts) {
}
}

if (opts.csp) {
opts.setHeaders = res => {
res.setHeader('Content-Security-Policy', opts.csp)
}
}

let server;
let fn = sirv(dir, opts);
let { hrtime, stdout } = process;
Expand Down
3 changes: 2 additions & 1 deletion packages/sirv-cli/readme.md
Expand Up @@ -48,6 +48,7 @@ $ sirv --help
-D, --dev Enable "dev" mode
-e, --etag Enable "ETag" header
-d, --dotfiles Enable dotfile asset requests
-C, --csp Enable Content-Security-Policy headers
-c, --cors Enable "CORS" headers to allow any origin requestor
-G, --gzip Send precompiled "*.gz" files when "gzip" is supported (default true)
-B, --brotli Send precompiled "*.br" files when "brotli" is supported (default true)
Expand All @@ -66,7 +67,7 @@ $ sirv --help
-h, --help Displays this message

Examples
$ sirv build --cors --port 8888
$ sirv build --cors --csp "default-src example.com" --port 8888
$ sirv public --quiet --etag --maxage 31536000 --immutable
$ sirv public --http2 --key priv.pem --cert cert.pem
$ sirv public -qeim 31536000
Expand Down
23 changes: 22 additions & 1 deletion tests/sirv-cli.js
Expand Up @@ -22,6 +22,7 @@ help('--help', () => {
-D, --dev Enable "dev" mode
-e, --etag Enable "ETag" header
-d, --dotfiles Enable dotfile asset requests
-C, --csp Enable Content-Security-Policy headers
-c, --cors Enable "CORS" headers to allow any origin requestor
-G, --gzip Send precompiled "*.gz" files when "gzip" is supported (default true)
-B, --brotli Send precompiled "*.br" files when "brotli" is supported (default true)
Expand All @@ -40,7 +41,7 @@ help('--help', () => {
-h, --help Displays this message

Examples
$ sirv build --cors --port 8888
$ sirv build --cors --csp "default-src example.com" --port 8888
$ sirv public --quiet --etag --maxage 31536000 --immutable
$ sirv public --http2 --key priv.pem --cert cert.pem
$ sirv public -qeim 31536000
Expand Down Expand Up @@ -71,6 +72,26 @@ basic.run();

// ---

const csp = suite('csp');

csp('should attach CSP headers to response', async () => {
let server = await utils.spawn('--csp "default-src example.com"');

try {
let res = await server.send('GET', '/blog');
await utils.matches(res, 200, 'blog.html', 'utf8');
assert.is(res.headers['Content-Security-Policy'], 'default-src example.com');
} finally {
await server.close();
}
});

csp.run();

// ---

// ---

const cors = suite('cors');

cors('should attach CORS headers to response', async () => {
Expand Down