diff --git a/packages/next/next-server/server/next-server.ts b/packages/next/next-server/server/next-server.ts index dac09e2b3dabc..8d72e1f011491 100644 --- a/packages/next/next-server/server/next-server.ts +++ b/packages/next/next-server/server/next-server.ts @@ -4,6 +4,7 @@ import { IncomingMessage, ServerResponse } from 'http' import { join, resolve, sep } from 'path' import { parse as parseQs, ParsedUrlQuery } from 'querystring' import { parse as parseUrl, UrlWithParsedQuery } from 'url' + import { withCoalescedInvoke } from '../../lib/coalesced-function' import { BUILD_ID_FILE, @@ -22,7 +23,7 @@ import { isDynamicRoute, } from '../lib/router/utils' import * as envConfig from '../lib/runtime-config' -import { NextApiRequest, NextApiResponse, isResSent } from '../lib/utils' +import { isResSent, NextApiRequest, NextApiResponse } from '../lib/utils' import { apiResolver } from './api-utils' import loadConfig, { isTargetLikeServerless } from './config' import { recursiveReadDirSync } from './lib/recursive-readdir-sync' @@ -32,9 +33,8 @@ import { getPagePath } from './require' import Router, { Params, route, Route, RouteMatch } from './router' import { sendHTML } from './send-html' import { serveStatic } from './serve-static' +import { getSprCache, initializeSprCache, setSprCache } from './spr-cache' import { isBlockedPage, isInternalUrl } from './utils' -import { findPagesDir } from '../../lib/find-pages-dir' -import { initializeSprCache, getSprCache, setSprCache } from './spr-cache' type NextConfig = any @@ -542,12 +542,18 @@ export default class Server { // TODO: ETag? Cache-Control headers? Next-specific headers? res.setHeader('Content-Type', type) res.setHeader('Content-Length', Buffer.byteLength(payload)) - - if (revalidate) { - res.setHeader( - 'Cache-Control', - `s-maxage=${revalidate}, stale-while-revalidate` - ) + if (!this.renderOpts.dev) { + if (revalidate) { + res.setHeader( + 'Cache-Control', + `s-maxage=${revalidate}, stale-while-revalidate` + ) + } else if (revalidate === false) { + res.setHeader( + 'Cache-Control', + `s-maxage=31536000, stale-while-revalidate` + ) + } } res.end(payload) } diff --git a/test/integration/prerender/test/index.test.js b/test/integration/prerender/test/index.test.js index f9340e24d3182..4f2bd8fb1721f 100644 --- a/test/integration/prerender/test/index.test.js +++ b/test/integration/prerender/test/index.test.js @@ -5,6 +5,7 @@ import { join } from 'path' import webdriver from 'next-webdriver' import { renderViaHTTP, + fetchViaHTTP, findPort, launchApp, killApp, @@ -202,14 +203,20 @@ const runTests = (dev = false) => { if (dev) { it('should always call getStaticProps without caching in dev', async () => { - const initialHtml = await renderViaHTTP(appPort, '/something') + const initialRes = await fetchViaHTTP(appPort, '/something') + expect(initialRes.headers.get('cache-control')).toBeFalsy() + const initialHtml = await initialRes.text() expect(initialHtml).toMatch(/hello.*?world/) - const newHtml = await renderViaHTTP(appPort, '/something') + const newRes = await fetchViaHTTP(appPort, '/something') + expect(newRes.headers.get('cache-control')).toBeFalsy() + const newHtml = await newRes.text() expect(newHtml).toMatch(/hello.*?world/) expect(initialHtml !== newHtml).toBe(true) - const newerHtml = await renderViaHTTP(appPort, '/something') + const newerRes = await fetchViaHTTP(appPort, '/something') + expect(newerRes.headers.get('cache-control')).toBeFalsy() + const newerHtml = await newerRes.text() expect(newerHtml).toMatch(/hello.*?world/) expect(newHtml !== newerHtml).toBe(true) }) @@ -230,6 +237,15 @@ const runTests = (dev = false) => { } }) } else { + it('should should use correct caching headers for a no-revalidate page', async () => { + const initialRes = await fetchViaHTTP(appPort, '/something') + expect(initialRes.headers.get('cache-control')).toBe( + 's-maxage=31536000, stale-while-revalidate' + ) + const initialHtml = await initialRes.text() + expect(initialHtml).toMatch(/hello.*?world/) + }) + it('outputs a prerender-manifest correctly', async () => { const manifest = JSON.parse( await fs.readFile(join(appDir, '.next/prerender-manifest.json'), 'utf8')