Skip to content

Commit

Permalink
Rename header conversion functions (#50389)
Browse files Browse the repository at this point in the history
To prevent confusion with`IncomingHttpHeaders`, this renames the functions used to convert back and forth between `OutgoingHttpHeaders` and `Headers`:

- Rename `fromNodeHeaders` to `fromNodeOutgoingHttpHeaders`
- Rename `toNodeHeaders` to `toNodeOutgoingHttpHeaders`
  • Loading branch information
wyattjoh committed May 26, 2023
1 parent 466d199 commit 10b82ba
Show file tree
Hide file tree
Showing 11 changed files with 57 additions and 38 deletions.
4 changes: 2 additions & 2 deletions packages/next/src/export/worker.ts
Expand Up @@ -43,7 +43,7 @@ import { NEXT_DYNAMIC_NO_SSR_CODE } from '../shared/lib/lazy-dynamic/no-ssr-erro
import { createRequestResponseMocks } from '../server/lib/mock-request'
import { NodeNextRequest } from '../server/base-http/node'
import { isAppRouteRoute } from '../lib/is-app-route-route'
import { toNodeHeaders } from '../server/web/utils'
import { toNodeOutgoingHttpHeaders } from '../server/web/utils'
import { RouteModuleLoader } from '../server/future/helpers/module-loader/route-module-loader'
import { NextRequestAdapter } from '../server/web/spec-extension/adapters/next-request'
import * as ciEnvironment from '../telemetry/ci-info'
Expand Down Expand Up @@ -445,7 +445,7 @@ export default async function exportPage({
context.staticGenerationContext.store?.revalidate || false

results.fromBuildExportRevalidate = revalidate
const headers = toNodeHeaders(response.headers)
const headers = toNodeOutgoingHttpHeaders(response.headers)
const cacheTags = (context.staticGenerationContext as any)
.fetchTags

Expand Down
4 changes: 2 additions & 2 deletions packages/next/src/server/base-http/web.ts
@@ -1,5 +1,5 @@
import type { IncomingHttpHeaders, OutgoingHttpHeaders } from 'http'
import { toNodeHeaders } from '../web/utils'
import { toNodeOutgoingHttpHeaders } from '../web/utils'

import { BaseNextRequest, BaseNextResponse } from './index'

Expand Down Expand Up @@ -81,7 +81,7 @@ export class WebNextResponse extends BaseNextResponse<WritableStream> {
}

getHeaders(): OutgoingHttpHeaders {
return toNodeHeaders(this.headers)
return toNodeOutgoingHttpHeaders(this.headers)
}

hasHeader(name: string): boolean {
Expand Down
9 changes: 6 additions & 3 deletions packages/next/src/server/base-server.ts
Expand Up @@ -100,7 +100,10 @@ import { I18NProvider } from './future/helpers/i18n-provider'
import { sendResponse } from './send-response'
import { RouteKind } from './future/route-kind'
import { handleInternalServerErrorResponse } from './future/route-modules/helpers/response-handlers'
import { fromNodeHeaders, toNodeHeaders } from './web/utils'
import {
fromNodeOutgoingHttpHeaders,
toNodeOutgoingHttpHeaders,
} from './web/utils'
import { NEXT_QUERY_PARAM_PREFIX } from '../lib/constants'

export type FindComponentsResult = {
Expand Down Expand Up @@ -1626,7 +1629,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
const blob = await response.blob()

// Copy the headers from the response.
const headers = toNodeHeaders(response.headers)
const headers = toNodeOutgoingHttpHeaders(response.headers)

if (cacheTags) {
headers['x-next-cache-tags'] = cacheTags
Expand Down Expand Up @@ -2024,7 +2027,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
req,
res,
new Response(cachedData.body, {
headers: fromNodeHeaders(headers),
headers: fromNodeOutgoingHttpHeaders(headers),
status: cachedData.status || 200,
})
)
Expand Down
4 changes: 2 additions & 2 deletions packages/next/src/server/lib/mock-request.ts
Expand Up @@ -9,7 +9,7 @@ import type { Socket } from 'net'
import type { TLSSocket } from 'tls'

import Stream from 'stream'
import { toNodeHeaders } from '../web/utils'
import { toNodeOutgoingHttpHeaders } from '../web/utils'

interface MockedRequestOptions {
url: string
Expand Down Expand Up @@ -240,7 +240,7 @@ export class MockedResponse extends Stream.Writable implements ServerResponse {
}

public getHeaders(): OutgoingHttpHeaders {
return toNodeHeaders(this.headers)
return toNodeOutgoingHttpHeaders(this.headers)
}

public getHeaderNames(): string[] {
Expand Down
6 changes: 3 additions & 3 deletions packages/next/src/server/next-server.ts
Expand Up @@ -78,7 +78,7 @@ import { normalizePagePath } from '../shared/lib/page-path/normalize-page-path'
import { loadComponents } from './load-components'
import isError, { getProperError } from '../lib/is-error'
import { FontManifest } from './font-utils'
import { splitCookiesString, toNodeHeaders } from './web/utils'
import { splitCookiesString, toNodeOutgoingHttpHeaders } from './web/utils'
import { relativizeURL } from '../shared/lib/router/utils/relativize-url'
import { prepareDestination } from '../shared/lib/router/utils/prepare-destination'
import { getMiddlewareRouteMatcher } from '../shared/lib/router/utils/middleware-route-matcher'
Expand Down Expand Up @@ -2496,7 +2496,7 @@ export default class NextNodeServer extends BaseServer {

if (isMiddlewareInvoke && 'response' in result) {
for (const [key, value] of Object.entries(
toNodeHeaders(result.response.headers)
toNodeOutgoingHttpHeaders(result.response.headers)
)) {
if (key !== 'content-encoding' && value !== undefined) {
res.setHeader(key, value as string | string[])
Expand Down Expand Up @@ -2590,7 +2590,7 @@ export default class NextNodeServer extends BaseServer {
result.response.headers.delete('x-middleware-next')

for (const [key, value] of Object.entries(
toNodeHeaders(result.response.headers)
toNodeOutgoingHttpHeaders(result.response.headers)
)) {
if (
[
Expand Down
4 changes: 2 additions & 2 deletions packages/next/src/server/web/adapter.ts
@@ -1,7 +1,7 @@
import type { NextMiddleware, RequestData, FetchEventResult } from './types'
import type { RequestInit } from './spec-extension/request'
import { PageSignatureError } from './error'
import { fromNodeHeaders } from './utils'
import { fromNodeOutgoingHttpHeaders } from './utils'
import { NextFetchEvent } from './spec-extension/fetch-event'
import { NextRequest } from './spec-extension/request'
import { NextResponse } from './spec-extension/response'
Expand Down Expand Up @@ -127,7 +127,7 @@ export async function adapter(
requestUrl.pathname = '/'
}

const requestHeaders = fromNodeHeaders(params.request.headers)
const requestHeaders = fromNodeOutgoingHttpHeaders(params.request.headers)
const flightHeaders = new Map()
// Parameters should only be stripped for middleware
if (!isEdgeRendering) {
Expand Down
Expand Up @@ -3,7 +3,7 @@ import type { NodeNextRequest } from '../../../base-http/node'
import type { WebNextRequest } from '../../../base-http/web'

import { getRequestMeta } from '../../../request-meta'
import { fromNodeHeaders } from '../../utils'
import { fromNodeOutgoingHttpHeaders } from '../../utils'
import { NextRequest } from '../request'

export class NextRequestAdapter {
Expand Down Expand Up @@ -38,7 +38,7 @@ export class NextRequestAdapter {
return new NextRequest(url, {
body,
method: request.method,
headers: fromNodeHeaders(request.headers),
headers: fromNodeOutgoingHttpHeaders(request.headers),
// @ts-expect-error - see https://github.com/whatwg/fetch/pull/1457
duplex: 'half',
// geo
Expand All @@ -57,7 +57,7 @@ export class NextRequestAdapter {
return new NextRequest(request.url, {
body,
method: request.method,
headers: fromNodeHeaders(request.headers),
headers: fromNodeOutgoingHttpHeaders(request.headers),
// @ts-expect-error - see https://github.com/whatwg/fetch/pull/1457
duplex: 'half',
// geo
Expand Down
4 changes: 2 additions & 2 deletions packages/next/src/server/web/spec-extension/request.ts
@@ -1,7 +1,7 @@
import type { I18NConfig } from '../../config-shared'
import type { RequestData } from '../types'
import { NextURL } from '../next-url'
import { toNodeHeaders, validateURL } from '../utils'
import { toNodeOutgoingHttpHeaders, validateURL } from '../utils'
import { RemovedUAError, RemovedPageError } from '../error'
import { RequestCookies } from './cookies'

Expand All @@ -22,7 +22,7 @@ export class NextRequest extends Request {
validateURL(url)
super(url, init)
const nextUrl = new NextURL(url, {
headers: toNodeHeaders(this.headers),
headers: toNodeOutgoingHttpHeaders(this.headers),
nextConfig: init.nextConfig,
})
this[INTERNALS] = {
Expand Down
4 changes: 2 additions & 2 deletions packages/next/src/server/web/spec-extension/response.ts
@@ -1,6 +1,6 @@
import type { I18NConfig } from '../../config-shared'
import { NextURL } from '../next-url'
import { toNodeHeaders, validateURL } from '../utils'
import { toNodeOutgoingHttpHeaders, validateURL } from '../utils'

import { ResponseCookies } from './cookies'

Expand Down Expand Up @@ -40,7 +40,7 @@ export class NextResponse<Body = unknown> extends Response {
cookies: new ResponseCookies(this.headers),
url: init.url
? new NextURL(init.url, {
headers: toNodeHeaders(this.headers),
headers: toNodeOutgoingHttpHeaders(this.headers),
nextConfig: init.nextConfig,
})
: undefined,
Expand Down
16 changes: 6 additions & 10 deletions packages/next/src/server/web/utils.test.ts
@@ -1,4 +1,4 @@
import { toNodeHeaders } from './utils'
import { toNodeOutgoingHttpHeaders } from './utils'

// We use `Headers` here which is provided by the polyfill.
import '../node-polyfill-fetch'
Expand All @@ -10,7 +10,7 @@ describe('toNodeHeaders', () => {
headers.append('set-cookie', 'foo=bar')
headers.append('set-cookie', 'bar=foo')

expect(toNodeHeaders(headers)).toEqual({
expect(toNodeOutgoingHttpHeaders(headers)).toEqual({
'set-cookie': ['foo=bar', 'bar=foo'],
})
})
Expand All @@ -20,7 +20,7 @@ describe('toNodeHeaders', () => {

headers.append('set-cookie', 'foo=bar')

expect(toNodeHeaders(headers)).toEqual({
expect(toNodeOutgoingHttpHeaders(headers)).toEqual({
'set-cookie': 'foo=bar',
})
})
Expand All @@ -30,13 +30,13 @@ describe('toNodeHeaders', () => {

headers.append('set-cookie', 'foo=bar, bar=foo')

expect(toNodeHeaders(headers)).toEqual({
expect(toNodeOutgoingHttpHeaders(headers)).toEqual({
'set-cookie': ['foo=bar', 'bar=foo'],
})

headers.append('set-cookie', 'baz=qux')

expect(toNodeHeaders(headers)).toEqual({
expect(toNodeOutgoingHttpHeaders(headers)).toEqual({
'set-cookie': ['foo=bar', 'bar=foo', 'baz=qux'],
})
})
Expand All @@ -47,12 +47,8 @@ describe('toNodeHeaders', () => {
headers.append('set-cookie', 'foo=bar')
headers.append('Set-Cookie', 'bar=foo')

expect(toNodeHeaders(headers)).toEqual({
expect(toNodeOutgoingHttpHeaders(headers)).toEqual({
'set-cookie': ['foo=bar', 'bar=foo'],
})
})

it('should return an empty object when no headers are provided', () => {
expect(toNodeHeaders()).toEqual({})
})
})
34 changes: 27 additions & 7 deletions packages/next/src/server/web/utils.ts
@@ -1,8 +1,19 @@
import type { OutgoingHttpHeaders } from 'http'

export function fromNodeHeaders(object: OutgoingHttpHeaders): Headers {
/**
* Converts a Node.js IncomingHttpHeaders object to a Headers object. Any
* headers with multiple values will be joined with a comma and space. Any
* headers that have an undefined value will be ignored and others will be
* coerced to strings.
*
* @param nodeHeaders the headers object to convert
* @returns the converted headers object
*/
export function fromNodeOutgoingHttpHeaders(
nodeHeaders: OutgoingHttpHeaders
): Headers {
const headers = new Headers()
for (let [key, value] of Object.entries(object)) {
for (let [key, value] of Object.entries(nodeHeaders)) {
const values = Array.isArray(value) ? value : [value]
for (let v of values) {
if (typeof v === 'undefined') continue
Expand Down Expand Up @@ -92,8 +103,17 @@ export function splitCookiesString(cookiesString: string) {
return cookiesStrings
}

export function toNodeHeaders(headers?: Headers): OutgoingHttpHeaders {
const result: OutgoingHttpHeaders = {}
/**
* Converts a Headers object to a Node.js OutgoingHttpHeaders object. This is
* required to support the set-cookie header, which may have multiple values.
*
* @param headers the headers object to convert
* @returns the converted headers object
*/
export function toNodeOutgoingHttpHeaders(
headers: Headers
): OutgoingHttpHeaders {
const nodeHeaders: OutgoingHttpHeaders = {}
const cookies: string[] = []
if (headers) {
for (const [key, value] of headers.entries()) {
Expand All @@ -102,13 +122,13 @@ export function toNodeHeaders(headers?: Headers): OutgoingHttpHeaders {
// set-cookie headers. We need to merge them into one header array
// to represent all the cookies.
cookies.push(...splitCookiesString(value))
result[key] = cookies.length === 1 ? cookies[0] : cookies
nodeHeaders[key] = cookies.length === 1 ? cookies[0] : cookies
} else {
result[key] = value
nodeHeaders[key] = value
}
}
}
return result
return nodeHeaders
}

/**
Expand Down

0 comments on commit 10b82ba

Please sign in to comment.