Skip to content

Commit fbe076b

Browse files
fix: Ensure to delete cookies when switching from single to chunks and vica versa
1 parent 65ece16 commit fbe076b

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

src/server/chunked-cookies.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,49 @@ describe("Chunked Cookie Utils", () => {
166166
);
167167
});
168168

169+
it("should clear existing chunked cookies when setting a single cookie", () => {
170+
const name = "testCookie";
171+
const value = "small value";
172+
const options = { path: "/" } as CookieOptions;
173+
174+
const chunk0 = "chunk0 value";
175+
const chunk1 = "chunk1 value";
176+
const chunk2 = "chunk2 value";
177+
178+
cookieStore.set(`${name}__1`, chunk1);
179+
cookieStore.set(`${name}__0`, chunk0);
180+
cookieStore.set(`${name}__2`, chunk2);
181+
182+
setChunkedCookie(name, value, options, reqCookies, resCookies);
183+
184+
expect(resCookies.set).toHaveBeenCalledTimes(1);
185+
expect(resCookies.set).toHaveBeenCalledWith(name, value, options);
186+
expect(reqCookies.set).toHaveBeenCalledTimes(1);
187+
expect(reqCookies.set).toHaveBeenCalledWith(name, value);
188+
expect(reqCookies.delete).toHaveBeenCalledTimes(3);
189+
expect(reqCookies.delete).toHaveBeenCalledWith(`${name}__0`);
190+
expect(reqCookies.delete).toHaveBeenCalledWith(`${name}__1`);
191+
expect(reqCookies.delete).toHaveBeenCalledWith(`${name}__2`);
192+
});
193+
194+
it("should clear existing single cookies when setting a chunked cookie", () => {
195+
const name = "testCookie";
196+
const value = "small value";
197+
198+
cookieStore.set(`${name}`, value);
199+
200+
// Create a large string (8000 bytes)
201+
const largeValue = "a".repeat(8000);
202+
const options = { path: "/" } as CookieOptions;
203+
204+
setChunkedCookie(name, largeValue, options, reqCookies, resCookies);
205+
206+
expect(reqCookies.delete).toHaveBeenCalledTimes(1);
207+
expect(reqCookies.delete).toHaveBeenCalledWith(`${name}`);
208+
expect(resCookies.set).toHaveBeenCalledTimes(3);
209+
expect(reqCookies.set).toHaveBeenCalledTimes(3);
210+
});
211+
169212
it("should clean up unused chunks when cookie shrinks", () => {
170213
const name = "testCookie";
171214
const options = { path: "/" } as CookieOptions;

src/server/cookies.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,13 @@ export function setChunkedCookie(
196196
resCookies.set(name, value, options);
197197
// to enable read-after-write in the same request for middleware
198198
reqCookies.set(name, value);
199+
200+
// When we are writing a non-chunked cookie, we should remove the chunked cookies
201+
getAllChunkedCookies(reqCookies, name).forEach(cookieChunk => {
202+
resCookies.delete(cookieChunk.name);
203+
reqCookies.delete(cookieChunk.name);
204+
});
205+
199206
return;
200207
}
201208

@@ -226,6 +233,10 @@ export function setChunkedCookie(
226233
reqCookies.delete(chunkName);
227234
}
228235
}
236+
237+
// When we have written chunked cookies, we should remove the non-chunked cookie
238+
resCookies.delete(name);
239+
reqCookies.delete(name);
229240
}
230241

231242
/**

0 commit comments

Comments
 (0)