diff --git a/.changeset/old-houses-film.md b/.changeset/old-houses-film.md new file mode 100644 index 00000000..0b55ed27 --- /dev/null +++ b/.changeset/old-houses-film.md @@ -0,0 +1,7 @@ +--- +'@edge-runtime/cookies': minor +'edge-runtime': path +--- + +feat(cookies): expose splitCookiesString function +fix: splitting cookies when concatenated diff --git a/packages/cookies/src/index.ts b/packages/cookies/src/index.ts index 58b4c784..57ae5867 100644 --- a/packages/cookies/src/index.ts +++ b/packages/cookies/src/index.ts @@ -1,4 +1,9 @@ export type { CookieListItem, RequestCookie, ResponseCookie } from './types' export { RequestCookies } from './request-cookies' export { ResponseCookies } from './response-cookies' -export { stringifyCookie, parseCookie, parseSetCookie } from './serialize' +export { + stringifyCookie, + parseCookie, + parseSetCookie, + splitCookiesString, +} from './serialize' diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 3655f281..5a291def 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -24,6 +24,7 @@ "web" ], "dependencies": { + "@edge-runtime/cookies": "workspace:*", "@edge-runtime/format": "workspace:*", "@edge-runtime/ponyfill": "workspace:*", "@edge-runtime/vm": "workspace:*", diff --git a/packages/runtime/src/server/create-handler.ts b/packages/runtime/src/server/create-handler.ts index 5cff7636..e7bdc39e 100644 --- a/packages/runtime/src/server/create-handler.ts +++ b/packages/runtime/src/server/create-handler.ts @@ -2,6 +2,7 @@ import type { EdgeRuntime } from '../edge-runtime' import type { IncomingMessage, ServerResponse } from 'http' import type { Logger, NodeHeaders } from '../types' import type { EdgeContext } from '@edge-runtime/vm' +import { splitCookiesString } from '@edge-runtime/cookies' import { getClonableBodyStream, pipeBodyStreamToResponse } from './body-streams' import prettyMs from 'pretty-ms' import timeSpan from 'time-span' @@ -112,13 +113,15 @@ function toRequestInitHeaders(req: IncomingMessage): RequestInit['headers'] { /** * Transforms WHATWG Headers into a Node Headers shape. Copies all items but - * does a special case for Set-Cookie using the [`getSetCookie`](https://developer.mozilla.org/en-US/docs/Web/API/Headers/getSetCookie) method. + * does a special case for Set-Cookie header field-values are sometimes comma joined in one string. This splits them without choking on commas + * that are within a single set-cookie field-value, such as in the Expires portion. */ function toNodeHeaders(headers?: Headers): NodeHeaders { const result: NodeHeaders = {} if (headers) { for (const [key, value] of headers.entries()) { - result[key] = key === 'set-cookie' ? headers.getSetCookie() : value + result[key] = + key?.toLowerCase() === 'set-cookie' ? splitCookiesString(value) : value } } return result diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e9133853..77895581 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + importers: .: @@ -240,6 +244,9 @@ importers: packages/runtime: dependencies: + '@edge-runtime/cookies': + specifier: workspace:* + version: link:../cookies '@edge-runtime/format': specifier: workspace:* version: link:../format @@ -8645,7 +8652,3 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} dev: false - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false