File tree Expand file tree Collapse file tree 3 files changed +32
-4
lines changed
Expand file tree Collapse file tree 3 files changed +32
-4
lines changed Original file line number Diff line number Diff line change @@ -17,3 +17,20 @@ export const MAX_REQUEST_TIMEOUT = process.env.REQUEST_TIMEOUT
1717 ? parseInt ( process . env . REQUEST_TIMEOUT , 10 )
1818 : DEFAULT_MAX_REQUEST_TIMEOUT
1919export const TRANSLATIONS_FIXTURE_ROOT = process . env . TRANSLATIONS_FIXTURE_ROOT
20+
21+ // Minimum required HTML for 404: W3C valid, no external, legal.
22+ export const minimumNotFoundHtml = `
23+ <!doctype html>
24+ <html lang=en>
25+ <meta charset=utf-8>
26+ <title>404 - GitHub Docs</title>
27+ <style>body{font-family:system-ui,sans-serif;margin:3rem}a{color:#0969DA}</style>
28+ <p style=font-weight:500>GitHub Docs</p>
29+ <p>Page not found.</p>
30+ <p><a href=/>Return to home.</a></p>
31+ <small>
32+ © ${ new Date ( ) . getFullYear ( ) } GitHub, Inc.
33+ • <a href=https://docs.github.com/site-policy/github-terms/github-terms-of-service>Terms</a>
34+ • <a href=https://docs.github.com/site-policy/privacy-policies/github-privacy-statement>Privacy</a>
35+ </small>
36+ ` . replace ( / \n / g, '' )
Original file line number Diff line number Diff line change @@ -11,6 +11,7 @@ import { allVersions } from '#src/versions/lib/all-versions.js'
1111import { isConnectionDropped } from './halt-on-dropped-connection.js'
1212import { nextHandleRequest } from './next.js'
1313import { defaultCacheControl } from './cache-control.js'
14+ import { minimumNotFoundHtml } from '../lib/constants.js'
1415
1516const STATSD_KEY_RENDER = 'middleware.render_page'
1617const STATSD_KEY_404 = 'middleware.render_404'
@@ -59,7 +60,7 @@ export default async function renderPage(req, res) {
5960
6061 if ( ! pathLanguagePrefixed ( req . path ) ) {
6162 defaultCacheControl ( res )
62- return res . status ( 404 ) . type ( 'text ' ) . send ( 'Not found' )
63+ return res . status ( 404 ) . type ( 'html ' ) . send ( minimumNotFoundHtml )
6364 }
6465
6566 // The rest is "unhandled" requests where we don't have the page
Original file line number Diff line number Diff line change @@ -126,18 +126,28 @@ describe('rate limiting', () => {
126126} )
127127
128128describe ( '404 pages and their content-type' , ( ) => {
129+ const exampleNonLanguage404plain = [ '/_next/image/foo' ]
130+ test . each ( exampleNonLanguage404plain ) (
131+ 'non-language 404 response is plain text and cacheable: %s' ,
132+ async ( pathname ) => {
133+ const res = await get ( pathname )
134+ expect ( res . statusCode ) . toBe ( 404 )
135+ expect ( res . headers [ 'content-type' ] ) . toMatch ( 'text/plain' )
136+ expect ( res . headers [ 'cache-control' ] ) . toMatch ( 'public' )
137+ } ,
138+ )
139+
129140 const exampleNonLanguage404s = [
130- '/_next/image/foo' ,
131141 '/wp-content/themes/seotheme/db.php?u' ,
132142 '/enterprise/3.1/_next/static/chunks/616-910d0397bafa52e0.js' ,
133143 '/~root' ,
134144 ]
135145 test . each ( exampleNonLanguage404s ) (
136- 'non-language 404 response is plain text and cacheable: %s' ,
146+ 'non-language 404 response is html text and cacheable: %s' ,
137147 async ( pathname ) => {
138148 const res = await get ( pathname )
139149 expect ( res . statusCode ) . toBe ( 404 )
140- expect ( res . headers [ 'content-type' ] ) . toMatch ( 'text/plain ' )
150+ expect ( res . headers [ 'content-type' ] ) . toMatch ( 'text/html; charset=utf-8 ' )
141151 expect ( res . headers [ 'cache-control' ] ) . toMatch ( 'public' )
142152 } ,
143153 )
You can’t perform that action at this time.
0 commit comments