From f8100ac74e4371a088d6ac85587f37d3a8ab6f24 Mon Sep 17 00:00:00 2001 From: Robert Knight <robertknight@gmail.com> Date: Thu, 31 Mar 2022 08:01:42 +0100 Subject: [PATCH] Add mechanism to specify custom headers for HTML test pages Add support for specifying custom headers to serve test pages with via inline `<!-- Header: <Key>:<Value> -->` comments in the HTML/XML, and change the existing XHTML test case to use it. --- dev-server/documents/html/xhtml-test.mustache | 7 ++++ dev-server/serve-dev.js | 38 ++++++++++++++----- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/dev-server/documents/html/xhtml-test.mustache b/dev-server/documents/html/xhtml-test.mustache index 7508be6e946..924d8dfee35 100644 --- a/dev-server/documents/html/xhtml-test.mustache +++ b/dev-server/documents/html/xhtml-test.mustache @@ -1,4 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + The dev server serves all HTML content with the text/html MIME type + by default. Much (most?) "XHTML" content on the web is served this way. + However serving with the correct MIME type affects browser behavior, so + it is important to use that here. +--> +<!-- Header: Content-Type: application/xhtml+xml --> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>XHTML test document</title> diff --git a/dev-server/serve-dev.js b/dev-server/serve-dev.js index 12b4167075c..29cccfa09e9 100644 --- a/dev-server/serve-dev.js +++ b/dev-server/serve-dev.js @@ -41,6 +41,27 @@ function renderScript(context) { return Mustache.render(scriptTemplate, context); } +/** + * Read tags in test pages specifying custom headers to serve the content with. + * + * These tags look like `<!-- Header: <Key>: <Value> -->`. + * + * @param {string} content + * @return {[key: string, value: string][]} + */ +function readCustomHeaderTags(content) { + return content + .split('\n') + .map(line => { + const keyValue = line.match(/<!--\s*Header:\s*([A-Za-z-]+):(.*)-->/); + if (!keyValue) { + return null; + } + return [keyValue[1], keyValue[2]]; + }) + .filter(kv => kv !== null); +} + /** * Build context for rendering templates in the defined views directory. * @@ -106,16 +127,13 @@ function serveDev(port, config) { // Serve HTML documents with injected client script app.get('/document/:document', (req, res, next) => { - // All HTML documents are served with the `text/html` mime type by default, - // even though some declare themselves to be XHTML. This mirrors how most - // content on the web is served. However we do have some test pages that - // need to be served with the correct XHTML mime type, as that alters - // browser behavior. See https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/XHTML. - if (req.params.document.startsWith('xhtml-')) { - res.set('Content-Type', 'application/xhtml+xml'); - } - - if (fs.existsSync(`${HTML_PATH}${req.params.document}.mustache`)) { + const path = `${HTML_PATH}${req.params.document}.mustache`; + if (fs.existsSync(path)) { + const content = fs.readFileSync(path, 'utf8'); + const headers = readCustomHeaderTags(content); + for (let [key, value] of headers) { + res.set(key, value); + } res.render(req.params.document, templateContext(config)); } else { next();