Skip to content
This repository was archived by the owner on Oct 22, 2025. It is now read-only.

Commit b33e234

Browse files
committed
fix(core): fix request not being passed to some lifecycle hooks (#1143)
1 parent 676e60d commit b33e234

File tree

6 files changed

+453
-1
lines changed

6 files changed

+453
-1
lines changed

packages/core/fixtures/driver-test-suite/registry.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ import {
4747
rawWebSocketNoAuthActor,
4848
rawWebSocketPublicActor,
4949
} from "./raw-websocket-auth";
50+
import { requestAccessActor } from "./request-access";
51+
import { requestAccessAuthActor } from "./request-access-auth";
5052
import { scheduled } from "./scheduled";
5153
import {
5254
driverCtxActor,
@@ -119,5 +121,8 @@ export const registry = setup({
119121
rawWebSocketNoAuthActor,
120122
rawWebSocketPublicActor,
121123
rawWebSocketCustomAuthActor,
124+
// From request-access.ts
125+
requestAccessActor,
126+
requestAccessAuthActor,
122127
},
123128
});
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { actor } from "@rivetkit/core";
2+
3+
/**
4+
* Test fixture to verify request object access in onAuth hook
5+
* onAuth runs on the HTTP server, not in the actor, so we test it separately
6+
*/
7+
export const requestAccessAuthActor = actor({
8+
onAuth: ({
9+
req,
10+
intents,
11+
params,
12+
}: {
13+
req: Request;
14+
intents: Set<string>;
15+
params?: { trackRequest?: boolean };
16+
}) => {
17+
if (params?.trackRequest) {
18+
// Extract request info and return it as auth data
19+
const headers: Record<string, string> = {};
20+
req.headers.forEach((value, key) => {
21+
headers[key] = value;
22+
});
23+
24+
return {
25+
hasRequest: true,
26+
requestUrl: req.url,
27+
requestMethod: req.method,
28+
requestHeaders: headers,
29+
intents: Array.from(intents),
30+
};
31+
}
32+
33+
// Return empty auth data when not tracking
34+
return {};
35+
},
36+
state: {
37+
authData: null as any,
38+
},
39+
onConnect: (c, conn) => {
40+
// Store auth data in state so we can retrieve it
41+
c.state.authData = conn.auth;
42+
},
43+
actions: {
44+
getAuthRequestInfo: (c) => {
45+
// Return the stored auth data or a default object
46+
const authData = c.state.authData || {
47+
hasRequest: false,
48+
requestUrl: null,
49+
requestMethod: null,
50+
requestHeaders: {},
51+
intents: [],
52+
};
53+
return authData;
54+
},
55+
},
56+
});
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import { actor } from "@rivetkit/core";
2+
3+
/**
4+
* Test fixture to verify request object access in all lifecycle hooks
5+
*/
6+
export const requestAccessActor = actor({
7+
onAuth: () => {}, // Allow unauthenticated connections
8+
state: {
9+
// Track request info from different hooks
10+
onBeforeConnectRequest: {
11+
hasRequest: false,
12+
requestUrl: null as string | null,
13+
requestMethod: null as string | null,
14+
requestHeaders: {} as Record<string, string>,
15+
},
16+
createConnStateRequest: {
17+
hasRequest: false,
18+
requestUrl: null as string | null,
19+
requestMethod: null as string | null,
20+
requestHeaders: {} as Record<string, string>,
21+
},
22+
onFetchRequest: {
23+
hasRequest: false,
24+
requestUrl: null as string | null,
25+
requestMethod: null as string | null,
26+
requestHeaders: {} as Record<string, string>,
27+
},
28+
onWebSocketRequest: {
29+
hasRequest: false,
30+
requestUrl: null as string | null,
31+
requestMethod: null as string | null,
32+
requestHeaders: {} as Record<string, string>,
33+
},
34+
},
35+
createConnState: (
36+
c,
37+
{
38+
params,
39+
request,
40+
}: { params?: { trackRequest?: boolean }; request?: Request },
41+
) => {
42+
if (params?.trackRequest && request) {
43+
c.state.createConnStateRequest.hasRequest = true;
44+
c.state.createConnStateRequest.requestUrl = request.url;
45+
c.state.createConnStateRequest.requestMethod = request.method;
46+
47+
// Store select headers
48+
const headers: Record<string, string> = {};
49+
request.headers.forEach((value, key) => {
50+
headers[key] = value;
51+
});
52+
c.state.createConnStateRequest.requestHeaders = headers;
53+
}
54+
55+
return {
56+
trackRequest: params?.trackRequest || false,
57+
};
58+
},
59+
onBeforeConnect: (c, { request, params }) => {
60+
if (params?.trackRequest) {
61+
if (request) {
62+
c.state.onBeforeConnectRequest.hasRequest = true;
63+
c.state.onBeforeConnectRequest.requestUrl = request.url;
64+
c.state.onBeforeConnectRequest.requestMethod = request.method;
65+
66+
// Store select headers
67+
const headers: Record<string, string> = {};
68+
request.headers.forEach((value, key) => {
69+
headers[key] = value;
70+
});
71+
c.state.onBeforeConnectRequest.requestHeaders = headers;
72+
} else {
73+
// Track that we tried but request was not available
74+
c.state.onBeforeConnectRequest.hasRequest = false;
75+
}
76+
}
77+
},
78+
onFetch: (c, request) => {
79+
// Store request info
80+
c.state.onFetchRequest.hasRequest = true;
81+
c.state.onFetchRequest.requestUrl = request.url;
82+
c.state.onFetchRequest.requestMethod = request.method;
83+
84+
// Store select headers
85+
const headers: Record<string, string> = {};
86+
request.headers.forEach((value, key) => {
87+
headers[key] = value;
88+
});
89+
c.state.onFetchRequest.requestHeaders = headers;
90+
91+
// Return response with request info
92+
return new Response(
93+
JSON.stringify({
94+
hasRequest: true,
95+
requestUrl: request.url,
96+
requestMethod: request.method,
97+
requestHeaders: headers,
98+
}),
99+
{
100+
status: 200,
101+
headers: { "Content-Type": "application/json" },
102+
},
103+
);
104+
},
105+
onWebSocket: (c, websocket, { request }) => {
106+
// Store request info
107+
c.state.onWebSocketRequest.hasRequest = true;
108+
c.state.onWebSocketRequest.requestUrl = request.url;
109+
c.state.onWebSocketRequest.requestMethod = request.method;
110+
111+
// Store select headers
112+
const headers: Record<string, string> = {};
113+
request.headers.forEach((value, key) => {
114+
headers[key] = value;
115+
});
116+
c.state.onWebSocketRequest.requestHeaders = headers;
117+
118+
// Send request info on connection
119+
websocket.send(
120+
JSON.stringify({
121+
hasRequest: true,
122+
requestUrl: request.url,
123+
requestMethod: request.method,
124+
requestHeaders: headers,
125+
}),
126+
);
127+
128+
// Echo messages back
129+
websocket.addEventListener("message", (event) => {
130+
websocket.send(event.data);
131+
});
132+
},
133+
actions: {
134+
getRequestInfo: (c) => {
135+
return {
136+
onBeforeConnect: c.state.onBeforeConnectRequest,
137+
createConnState: c.state.createConnStateRequest,
138+
onFetch: c.state.onFetchRequest,
139+
onWebSocket: c.state.onWebSocketRequest,
140+
};
141+
},
142+
},
143+
});

packages/core/src/driver-test-suite/mod.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { runRawHttpDirectRegistryTests } from "./tests/raw-http-direct-registry"
2525
import { runRawHttpRequestPropertiesTests } from "./tests/raw-http-request-properties";
2626
import { runRawWebSocketTests } from "./tests/raw-websocket";
2727
import { runRawWebSocketDirectRegistryTests } from "./tests/raw-websocket-direct-registry";
28+
import { runRequestAccessTests } from "./tests/request-access";
2829

2930
export interface SkipTests {
3031
schedule?: boolean;
@@ -90,6 +91,8 @@ export function runDriverTests(
9091
});
9192

9293
runActorConnStateTests({ ...driverTestConfig, transport });
94+
95+
runRequestAccessTests({ ...driverTestConfig, transport });
9396
});
9497
}
9598

0 commit comments

Comments
 (0)