Compare commits

..

16 Commits

Author SHA1 Message Date
Rich Harris
8c07d9d2ac -> v0.20.3 2018-09-08 10:24:21 -04:00
Rich Harris
7bd684a80e Merge pull request #428 from nolanlawson/cache-control-service-worker
Set service-worker max-age to 0
2018-09-08 10:20:04 -04:00
Rich Harris
cbb5e8755b Use MDN recommendation for preventing SW caching 2018-09-08 10:12:55 -04:00
Rich Harris
7ef72dbb77 Merge pull request #429 from nolanlawson/consistent-cache-control
Use consistent cache-control:max-age=600 for HTML pages
2018-09-08 09:40:56 -04:00
Nolan Lawson
87ff9c2aeb fix test 2018-09-07 17:25:17 -07:00
Nolan Lawson
2d1f535314 use consistent cache-control:max-age=600 for HTML pages 2018-09-07 16:46:40 -07:00
Rich Harris
cd1b53b80d Merge pull request #424 from nolanlawson/csp-nonce
Allow scripts to contain a CSP nonce
2018-09-07 19:46:07 -04:00
Rich Harris
0a7be736c0 snake_case 2018-09-07 19:45:40 -04:00
Nolan Lawson
5ee53a98c6 set service-worker max-age to 0 2018-09-07 16:28:38 -07:00
Rich Harris
0e8ed6612c -> v0.20.2 2018-09-07 18:19:39 -04:00
Rich Harris
5ec748b95d Merge pull request #427 from sveltejs/gh-426
handle value-less query string parameters
2018-09-07 18:18:28 -04:00
Rich Harris
64b16715cd handle value-less query string parameters - fixes #426 2018-09-07 18:02:58 -04:00
Rich Harris
9ea5e5e251 Merge pull request #425 from nolanlawson/cache-control-immutable
Add cache-control:immutable for immutable assets
2018-09-07 17:12:23 -04:00
Rich Harris
68b78f56d6 remove unused file 2018-09-07 16:42:56 -04:00
Nolan Lawson
68e93a8fa0 add cache-control:immutable for immutable assets 2018-09-07 11:07:50 -07:00
Nolan Lawson
e377515867 allow scripts to contain a CSP nonce 2018-09-07 09:46:53 -07:00
7 changed files with 51 additions and 12 deletions

View File

@@ -1,5 +1,16 @@
# sapper changelog
## 0.20.3
* Inject `nonce` attribute if `res.locals.nonce` is present ([#424](https://github.com/sveltejs/sapper/pull/424))
* Prevent service worker caching ([#428](https://github.com/sveltejs/sapper/pull/428))
* Consistent caching for HTML responses ([#429](https://github.com/sveltejs/sapper/pull/429))
## 0.20.2
* Add `immutable` cache control header for hashed assets ([#425](https://github.com/sveltejs/sapper/pull/425))
* Handle value-less query string params ([#426](https://github.com/sveltejs/sapper/issues/426))
## 0.20.1
* Update shimport

View File

@@ -1 +0,0 @@
<svelte:component this={child.component} {...child.props}/>

View File

@@ -1,6 +1,6 @@
{
"name": "sapper",
"version": "0.20.1",
"version": "0.20.3",
"description": "Military-grade apps, engineered by Svelte",
"main": "dist/middleware.js",
"bin": {

View File

@@ -136,22 +136,22 @@ export default function middleware(opts: {
fs.existsSync(path.join(output, 'index.html')) && serve({
pathname: '/index.html',
cache_control: 'max-age=600'
cache_control: dev() ? 'no-cache' : 'max-age=600'
}),
fs.existsSync(path.join(output, 'service-worker.js')) && serve({
pathname: '/service-worker.js',
cache_control: 'max-age=600'
cache_control: 'no-cache, no-store, must-revalidate'
}),
fs.existsSync(path.join(output, 'service-worker.js.map')) && serve({
pathname: '/service-worker.js.map',
cache_control: 'max-age=600'
cache_control: 'no-cache, no-store, must-revalidate'
}),
serve({
prefix: '/client/',
cache_control: dev() ? 'no-cache' : 'max-age=31536000'
cache_control: dev() ? 'no-cache' : 'max-age=31536000, immutable'
}),
get_server_route_handler(manifest.server_routes),
@@ -312,6 +312,7 @@ function get_page_handler(
} = get_build_info();
res.setHeader('Content-Type', 'text/html');
res.setHeader('Cache-Control', dev() ? 'no-cache' : 'max-age=600');
// preload main.js and current route
// TODO detect other stuff we can preload? images, CSS, fonts?
@@ -524,9 +525,12 @@ function get_page_handler(
styles = (css && css.code ? `<style>${css.code}</style>` : '');
}
// users can set a CSP nonce using res.locals.nonce
const nonce_attr = (res.locals && res.locals.nonce) ? ` nonce="${res.locals.nonce}"` : '';
const body = template()
.replace('%sapper.base%', () => `<base href="${req.baseUrl}/">`)
.replace('%sapper.scripts%', () => `<script>${script}</script>`)
.replace('%sapper.scripts%', () => `<script${nonce_attr}>${script}</script>`)
.replace('%sapper.html%', () => html)
.replace('%sapper.head%', () => `<noscript id='sapper-head-start'></noscript>${head}<noscript id='sapper-head-end'></noscript>`)
.replace('%sapper.styles%', () => styles);

View File

@@ -66,8 +66,8 @@ function select_route(url: URL): Target {
const query: Record<string, string | true> = {};
if (url.search.length > 0) {
url.search.slice(1).split('&').forEach(searchParam => {
const [, key, value] = /([^=]+)=(.*)/.exec(searchParam);
query[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : true;
const [, key, value] = /([^=]+)(?:=(.*))?/.exec(searchParam);
query[key] = decodeURIComponent((value || '').replace(/\+/g, ' '));
});
}
return { url, path, page, match, query };

View File

@@ -16,6 +16,7 @@
<a rel=prefetch class='{page === "blog" ? "selected" : ""}' href='blog'>blog</a>
<a href="const">const</a>
<a href="echo/page/encöded?message=hëllö+wörld">echo/page/encöded?message=hëllö+wörld</a>
<a href="echo/page/empty?message">echo/page/empty?message</a>
<div class='hydrate-test'></div>

View File

@@ -5,6 +5,7 @@ const Nightmare = require('nightmare');
const walkSync = require('walk-sync');
const rimraf = require('rimraf');
const ports = require('port-authority');
const fetch = require('node-fetch');
Nightmare.action('page', {
title(done) {
@@ -772,6 +773,24 @@ function run({ mode, basepath = '' }) {
});
});
it('accepts value-less query string parameter on server', () => {
return nightmare.goto(`${base}/echo/page/empty?message`)
.page.title()
.then(title => {
assert.equal(title, 'empty ()');
});
});
it('accepts value-less query string parameter on client', () => {
return nightmare.goto(base).init()
.click('a[href="echo/page/empty?message"]')
.wait(100)
.page.title()
.then(title => {
assert.equal(title, 'empty ()');
});
});
it('encodes req.params for server routes', () => {
return nightmare.goto(`${base}/echo/server-route/encöded`)
.page.title()
@@ -782,15 +801,20 @@ function run({ mode, basepath = '' }) {
});
describe('headers', () => {
it('sets Content-Type and Link...preload headers', () => {
return capture(() => nightmare.goto(base)).then(requests => {
const { headers } = requests[0];
it('sets Content-Type, Link...preload, and Cache-Control headers', () => {
return capture(() => fetch(base)).then(responses => {
const { headers } = responses[0];
assert.equal(
headers['content-type'],
'text/html'
);
assert.equal(
headers['cache-control'],
'max-age=600'
);
const str = ['main', '.+?\\.\\d+']
.map(file => {
return `<${basepath}/client/[^/]+/${file}\\.js>;rel="preload";as="script"`;