From f5b7065fc74f34133500247f52960abedd7290d3 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Tue, 22 Jun 2021 23:05:54 +0800 Subject: [PATCH] fix: ignore invalid accept-language header (#26476) Fixes #22329 ## Bug - [x] Related issues linked using fixes #22329 - [x] Integration tests added ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. ## Documentation / Examples - [ ] Make sure the linting passes --- .../loaders/next-serverless-loader/utils.ts | 13 +++++++---- .../next/next-server/server/next-server.ts | 14 +++++++----- .../i18n-support/test/index.test.js | 22 +++++++++++++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/packages/next/build/webpack/loaders/next-serverless-loader/utils.ts b/packages/next/build/webpack/loaders/next-serverless-loader/utils.ts index b8f7fdb4f14ad..8845ddc110b7d 100644 --- a/packages/next/build/webpack/loaders/next-serverless-loader/utils.ts +++ b/packages/next/build/webpack/loaders/next-serverless-loader/utils.ts @@ -351,10 +351,15 @@ export function getUtils({ let defaultLocale = i18n.defaultLocale let detectedLocale = detectLocaleCookie(req, i18n.locales) - let acceptPreferredLocale = - i18n.localeDetection !== false - ? accept.language(req.headers['accept-language'], i18n.locales) - : detectedLocale + let acceptPreferredLocale + try { + acceptPreferredLocale = + i18n.localeDetection !== false + ? accept.language(req.headers['accept-language'], i18n.locales) + : detectedLocale + } catch (_) { + acceptPreferredLocale = detectedLocale + } const { host } = req.headers || {} // remove port from host and remove port if present diff --git a/packages/next/next-server/server/next-server.ts b/packages/next/next-server/server/next-server.ts index 885937ea74b58..54594d035482e 100644 --- a/packages/next/next-server/server/next-server.ts +++ b/packages/next/next-server/server/next-server.ts @@ -427,11 +427,15 @@ export default class Server { let defaultLocale = i18n.defaultLocale let detectedLocale = detectLocaleCookie(req, i18n.locales) - let acceptPreferredLocale = - i18n.localeDetection !== false - ? accept.language(req.headers['accept-language'], i18n.locales) - : detectedLocale - + let acceptPreferredLocale + try { + acceptPreferredLocale = + i18n.localeDetection !== false + ? accept.language(req.headers['accept-language'], i18n.locales) + : detectedLocale + } catch (_) { + acceptPreferredLocale = detectedLocale + } const { host } = req?.headers || {} // remove port from host if present const hostname = host?.split(':')[0].toLowerCase() diff --git a/test/integration/i18n-support/test/index.test.js b/test/integration/i18n-support/test/index.test.js index 480c28d707130..ea82869ec6c74 100644 --- a/test/integration/i18n-support/test/index.test.js +++ b/test/integration/i18n-support/test/index.test.js @@ -267,6 +267,28 @@ describe('i18n Support', () => { expect($('#router-as-path').text()).toBe('/') }) + it('should ignore the invalid accept-language header', async () => { + nextConfig.replace('localeDetection: false', 'localeDetection: true') + const res = await fetchViaHTTP( + ctx.appPort, + '/', + {}, + { + headers: { + 'accept-language': 'ldfir;', + }, + } + ) + + expect(res.status).toBe(200) + const $ = cheerio.load(await res.text()) + expect($('html').attr('lang')).toBe('en-US') + expect($('#router-locale').text()).toBe('en-US') + expect(JSON.parse($('#router-locales').text())).toEqual(locales) + expect($('#router-pathname').text()).toBe('/') + expect($('#router-as-path').text()).toBe('/') + }) + it('should set locale from detected path', async () => { for (const locale of nonDomainLocales) { const res = await fetchViaHTTP(