diff --git a/server/render.js b/server/render.js index 699eef4f..eabcd659 100644 --- a/server/render.js +++ b/server/render.js @@ -185,7 +185,9 @@ export function sendHTML (req, res, html, method, { dev }) { } res.setHeader('ETag', etag) - res.setHeader('Content-Type', 'text/html') + if (!res.getHeader('Content-Type')) { + res.setHeader('Content-Type', 'text/html') + } res.setHeader('Content-Length', Buffer.byteLength(html)) res.end(method === 'HEAD' ? null : html) } diff --git a/test/integration/basic/pages/custom-encoding.js b/test/integration/basic/pages/custom-encoding.js new file mode 100644 index 00000000..e091c3c0 --- /dev/null +++ b/test/integration/basic/pages/custom-encoding.js @@ -0,0 +1,13 @@ +import React from 'react' +export default class extends React.Component { + static async getInitialProps ({res}) { + if (res) { + res.setHeader('Content-Type', 'text/html; charset=utf-8') + } + return {} + } + + render () { + return null + } +} diff --git a/test/integration/basic/test/index.test.js b/test/integration/basic/test/index.test.js index 5ff68a11..265e31d9 100644 --- a/test/integration/basic/test/index.test.js +++ b/test/integration/basic/test/index.test.js @@ -3,6 +3,7 @@ import { join } from 'path' import { renderViaHTTP, + fetchViaHTTP, findPort, launchApp, killApp @@ -55,7 +56,7 @@ describe('Basic Features', () => { }) afterAll(() => killApp(context.server)) - rendering(context, 'Rendering via HTTP', (p, q) => renderViaHTTP(context.appPort, p, q)) + rendering(context, 'Rendering via HTTP', (p, q) => renderViaHTTP(context.appPort, p, q), (p, q) => fetchViaHTTP(context.appPort, p, q)) clientNavigation(context, (p, q) => renderViaHTTP(context.appPort, p, q)) dynamic(context, (p, q) => renderViaHTTP(context.appPort, p, q)) hmr(context, (p, q) => renderViaHTTP(context.appPort, p, q)) diff --git a/test/integration/basic/test/rendering.js b/test/integration/basic/test/rendering.js index 21a85c6e..47391034 100644 --- a/test/integration/basic/test/rendering.js +++ b/test/integration/basic/test/rendering.js @@ -2,7 +2,7 @@ import cheerio from 'cheerio' -export default function ({ app }, suiteName, render) { +export default function ({ app }, suiteName, render, fetch) { async function get$ (path, query) { const html = await render(path, query) return cheerio.load(html) @@ -63,6 +63,16 @@ export default function ({ app }, suiteName, render) { expect($('pre').text().includes(expectedErrorMessage)).toBeTruthy() }) + test('default Content-Type', async () => { + const res = await fetch('/stateless') + expect(res.headers.get('Content-Type')).toMatch('text/html') + }) + + test('setting Content-Type in getInitialProps', async () => { + const res = await fetch('/custom-encoding') + expect(res.headers.get('Content-Type')).toMatch('text/html; charset=utf-8') + }) + test('allows to import .json files', async () => { const html = await render('/json') expect(html.includes('Zeit')).toBeTruthy() diff --git a/test/integration/production/test/index.test.js b/test/integration/production/test/index.test.js index 5128f707..09854e66 100644 --- a/test/integration/production/test/index.test.js +++ b/test/integration/production/test/index.test.js @@ -117,6 +117,9 @@ describe('Production Usage', () => { const req = { url: '/stateless', headers: {} } const headers = {} const res = { + getHeader (key) { + return headers[key] + }, setHeader (key, value) { headers[key] = value }, @@ -132,6 +135,9 @@ describe('Production Usage', () => { const originalConfigValue = app.config.poweredByHeader app.config.poweredByHeader = false const res = { + getHeader () { + return false + }, setHeader (key, value) { if (key === 'X-Powered-By') { throw new Error('Should not set the X-Powered-By header') diff --git a/test/lib/next-test-utils.js b/test/lib/next-test-utils.js index a8ac957b..60eadff2 100644 --- a/test/lib/next-test-utils.js +++ b/test/lib/next-test-utils.js @@ -23,8 +23,12 @@ export function renderViaAPI (app, pathname, query) { } export function renderViaHTTP (appPort, pathname, query) { + return fetchViaHTTP(appPort, pathname, query).then((res) => res.text()) +} + +export function fetchViaHTTP (appPort, pathname, query) { const url = `http://localhost:${appPort}${pathname}${query ? `?${qs.stringify(query)}` : ''}` - return fetch(url).then((res) => res.text()) + return fetch(url) } export function findPort () { diff --git a/yarn.lock b/yarn.lock index b124f165..df5aad7c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6071,9 +6071,9 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -styled-jsx@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-2.1.1.tgz#e7481c7554df50d605cdc84a4e53c58fec3449b5" +styled-jsx@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-2.1.2.tgz#c84823402678022355b090d98d959ba126b97911" dependencies: babel-plugin-syntax-jsx "6.18.0" babel-types "6.23.0"