Skip to content

Commit

Permalink
fix(server): unique context objects per request (#1246)
Browse files Browse the repository at this point in the history
  • Loading branch information
ardatan authored Apr 15, 2024
1 parent f4ca82a commit 4717be5
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 3 deletions.
9 changes: 9 additions & 0 deletions .changeset/violet-dancers-wash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@whatwg-node/server": patch
---

Ensure unique context objects are sent per each request.

For example in CloudFlare Workers,
`fetch` receives `env` and `ctx`, and `env` is shared across requests. That causes the server receives the same context object for each request.
Now the server creates a new context object for each request, even if the first argument is the same. Before, it always takes the first argument as the context object, then merges the following arguments into it.
3 changes: 2 additions & 1 deletion benchmarks/server/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"baseUrl": "./",
"outDir": "dist",
"module": "Node16",
"moduleResolution": "node16"
"moduleResolution": "node16",
"skipLibCheck": true
},
"include": ["server.ts"],
"exclude": []
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/createServerAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ function createServerAdapter<
let waitUntilPromises: Promise<void>[] | undefined;
const serverContext =
filteredCtxParts.length > 1
? completeAssign(...filteredCtxParts)
? completeAssign({}, ...filteredCtxParts)
: isolateObject(
filteredCtxParts[0],
filteredCtxParts[0] == null || filteredCtxParts[0].waitUntil == null
Expand Down
21 changes: 21 additions & 0 deletions packages/server/test/adapter.fetch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,4 +227,25 @@ describe('adapter.fetch', () => {
controller.abort();
await expect(promise).rejects.toThrow('This operation was aborted');
});

it('should provide a unique context for each request', async () => {
const requestHandler = jest.fn((_req: Request, _ctx: any) =>
Response.json({
hello: 'world',
}),
);
const sharedCtxPart1 = { foo: 'bar' };
const sharedCtxPart2 = { bar: 'baz' };
const adapter = createServerAdapter(requestHandler);
const request1 = new Request('http://localhost:8080/');
const response1 = await adapter.fetch(request1, sharedCtxPart1, sharedCtxPart2);
const response1Body = await response1.json();
expect(response1Body).toEqual({ hello: 'world' });
const request2 = new Request('http://localhost:8080/');
const response2 = await adapter.fetch(request2, sharedCtxPart1, sharedCtxPart2);
const response2Body = await response2.json();
expect(response2Body).toEqual({ hello: 'world' });
expect(requestHandler).toHaveBeenCalledTimes(2);
expect(requestHandler.mock.calls[0][1]).not.toBe(requestHandler.mock.calls[1][1]);
});
});
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@
"fetchache": ["packages/fetchache/src/index.ts"]
}
},
"include": ["packages", "examples", "uwsUtils.d.ts"],
"include": ["packages", "examples", "uwsUtils.d.ts", "scheduler-tracing.d.ts"],
"exclude": ["**/node_modules", "**/test-files", "**/dist", "**/e2e", "**/benchmark"]
}

0 comments on commit 4717be5

Please sign in to comment.