Skip to content

Commit

Permalink
feat(core): custom pushAssets function to control http2 push headers (#…
Browse files Browse the repository at this point in the history
…4198)

Resolves #4011
Resolves #4161
  • Loading branch information
awronski authored and pi0 committed Oct 26, 2018
1 parent ae9de93 commit c9fd780
Showing 1 changed file with 28 additions and 17 deletions.
45 changes: 28 additions & 17 deletions packages/core/src/middleware/nuxt.js
Expand Up @@ -44,30 +44,18 @@ export default async function nuxtMiddleware(req, res, next) {
if (!error && this.options.render.http2.push) {
// Parse resourceHints to extract HTTP.2 prefetch/push headers
// https://w3c.github.io/preload/#server-push-http-2
const pushAssets = []
const preloadFiles = getPreloadFiles()
const { shouldPush } = this.options.render.http2
const { shouldPush, pushAssets } = this.options.render.http2
const { publicPath } = this.resources.clientManifest

preloadFiles.forEach(({ file, asType, fileWithoutQuery }) => {
// By default, we only preload scripts or css
/* istanbul ignore if */
if (!shouldPush && asType !== 'script' && asType !== 'style') {
return
}

// User wants to explicitly control what to preload
if (shouldPush && !shouldPush(fileWithoutQuery, asType)) {
return
}

pushAssets.push(`<${publicPath}${file}>; rel=preload; as=${asType}`)
})
const links = pushAssets ? pushAssets(req, res, publicPath, preloadFiles) : defaultPushAssets(preloadFiles, shouldPush, publicPath, this.options.dev)

// Pass with single Link header
// https://blog.cloudflare.com/http-2-server-push-with-multiple-assets-per-link-header
// https://www.w3.org/Protocols/9707-link-header.html
res.setHeader('Link', pushAssets.join(','))
if (links.length > 0) {
res.setHeader('Link', links.join(', '))
}
}

if (this.options.render.csp) {
Expand All @@ -94,6 +82,29 @@ export default async function nuxtMiddleware(req, res, next) {
}
}

const defaultPushAssets = (preloadFiles, shouldPush, publicPath, isDev) => {
if (shouldPush && isDev) {
consola.warn('http2.shouldPush is deprecated. User http2.pushAssets function')
}

const links = []
preloadFiles.forEach(({ file, asType, fileWithoutQuery }) => {
// By default, we only preload scripts or css
/* istanbul ignore if */
if (!shouldPush && asType !== 'script' && asType !== 'style') {
return
}

// User wants to explicitly control what to preload
if (shouldPush && !shouldPush(fileWithoutQuery, asType)) {
return
}

links.push(`<${publicPath}${file}>; rel=preload; as=${asType}`)
})
return links
}

const getCspString = ({ cspScriptSrcHashSet, allowedSources, policies, isDev }) => {
const joinedHashSet = Array.from(cspScriptSrcHashSet).join(' ')
const baseCspStr = `script-src 'self'${isDev ? ` 'unsafe-eval'` : ''} ${joinedHashSet}`
Expand Down

0 comments on commit c9fd780

Please sign in to comment.