Skip to content

Commit 3ba72ca

Browse files
committed
fix(rivetkit): uri encode actor ids to fix cloudflare workers actor id with generation (#3504)
1 parent 05bfcb3 commit 3ba72ca

File tree

6 files changed

+22
-11
lines changed

6 files changed

+22
-11
lines changed

engine/packages/engine/tests/common/actors.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,10 @@ pub async fn ping_actor_websocket_via_guard(guard_port: u16, actor_id: &str) ->
437437
.expect("Failed to create WebSocket request");
438438

439439
// Add protocols for routing through guard to actor
440+
// URL encode the actor ID since colons are not allowed in WebSocket protocol names
440441
request.headers_mut().insert(
441442
"Sec-WebSocket-Protocol",
442-
format!("rivet, rivet_target.actor, rivet_actor.{}", actor_id)
443+
format!("rivet, rivet_target.actor, rivet_actor.{}", urlencoding::encode(&actor_id))
443444
.parse()
444445
.unwrap(),
445446
);

engine/packages/guard/src/routing/pegboard_gateway.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub async fn route_request(
6060

6161
let protocols: Vec<&str> = protocols_header.split(',').map(|p| p.trim()).collect();
6262

63-
let actor_id = protocols
63+
let actor_id_raw = protocols
6464
.iter()
6565
.find_map(|p| p.strip_prefix(WS_PROTOCOL_ACTOR))
6666
.ok_or_else(|| {
@@ -70,6 +70,10 @@ pub async fn route_request(
7070
.build()
7171
})?;
7272

73+
let actor_id = urlencoding::decode(actor_id_raw)
74+
.context("invalid url encoding in actor id")?
75+
.to_string();
76+
7377
let token = protocols
7478
.iter()
7579
.find_map(|p| p.strip_prefix(WS_PROTOCOL_TOKEN));
@@ -95,11 +99,11 @@ pub async fn route_request(
9599
.transpose()
96100
.context("invalid x-rivet-token header")?;
97101

98-
(actor_id, token)
102+
(actor_id.to_string(), token)
99103
};
100104

101105
// Find actor to route to
102-
let actor_id = Id::parse(actor_id_str).context("invalid x-rivet-actor header")?;
106+
let actor_id = Id::parse(&actor_id_str).context("invalid x-rivet-actor header")?;
103107

104108
route_request_inner(ctx, shared_state, actor_id, path, token).await
105109
}

rivetkit-typescript/packages/cloudflare-workers/src/manager-driver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export class CloudflareActorsManagerDriver implements ManagerDriver {
8686
const protocols: string[] = [];
8787
protocols.push(WS_PROTOCOL_STANDARD);
8888
protocols.push(`${WS_PROTOCOL_TARGET}actor`);
89-
protocols.push(`${WS_PROTOCOL_ACTOR}${actorId}`);
89+
protocols.push(`${WS_PROTOCOL_ACTOR}${encodeURIComponent(actorId)}`);
9090
protocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);
9191
if (params) {
9292
protocols.push(
@@ -205,7 +205,7 @@ export class CloudflareActorsManagerDriver implements ManagerDriver {
205205
const protocols: string[] = [];
206206
protocols.push(WS_PROTOCOL_STANDARD);
207207
protocols.push(`${WS_PROTOCOL_TARGET}actor`);
208-
protocols.push(`${WS_PROTOCOL_ACTOR}${actorId}`);
208+
protocols.push(`${WS_PROTOCOL_ACTOR}${encodeURIComponent(actorId)}`);
209209
protocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);
210210
if (params) {
211211
protocols.push(

rivetkit-typescript/packages/rivetkit/src/driver-test-suite/test-inline-client-driver.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
WS_PROTOCOL_ACTOR,
1313
WS_PROTOCOL_CONN_PARAMS,
1414
WS_PROTOCOL_ENCODING,
15+
WS_PROTOCOL_STANDARD,
1516
WS_PROTOCOL_TARGET,
1617
WS_TEST_PROTOCOL_PATH,
1718
} from "@/common/actor-router-consts";
@@ -180,12 +181,11 @@ export function createTestInlineClientDriver(
180181
const wsProtocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
181182
const finalWsUrl = `${wsProtocol}//${wsUrl.host}${wsUrl.pathname}`;
182183

183-
logger().debug({ msg: "connecting to websocket", url: finalWsUrl });
184-
185184
// Build protocols for the connection
186185
const protocols: string[] = [];
186+
protocols.push(WS_PROTOCOL_STANDARD);
187187
protocols.push(`${WS_PROTOCOL_TARGET}actor`);
188-
protocols.push(`${WS_PROTOCOL_ACTOR}${actorId}`);
188+
protocols.push(`${WS_PROTOCOL_ACTOR}${encodeURIComponent(actorId)}`);
189189
protocols.push(`${WS_PROTOCOL_ENCODING}${encoding}`);
190190
protocols.push(
191191
`${WS_TEST_PROTOCOL_PATH}${encodeURIComponent(normalizedPath)}`,
@@ -196,6 +196,12 @@ export function createTestInlineClientDriver(
196196
);
197197
}
198198

199+
logger().debug({
200+
msg: "connecting to websocket",
201+
url: finalWsUrl,
202+
protocols,
203+
});
204+
199205
// Create and return the WebSocket
200206
// Node & browser WebSocket types are incompatible
201207
const ws = new WebSocket(finalWsUrl, protocols) as any;

rivetkit-typescript/packages/rivetkit/src/manager/gateway.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ async function handleWebSocketGateway(
222222
if (protocol.startsWith(WS_PROTOCOL_TARGET)) {
223223
target = protocol.substring(WS_PROTOCOL_TARGET.length);
224224
} else if (protocol.startsWith(WS_PROTOCOL_ACTOR)) {
225-
actorId = protocol.substring(WS_PROTOCOL_ACTOR.length);
225+
actorId = decodeURIComponent(protocol.substring(WS_PROTOCOL_ACTOR.length));
226226
} else if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
227227
encodingRaw = protocol.substring(WS_PROTOCOL_ENCODING.length);
228228
} else if (protocol.startsWith(WS_PROTOCOL_CONN_PARAMS)) {

rivetkit-typescript/packages/rivetkit/src/manager/router.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ function addManagerRoutes(
565565

566566
for (const protocol of protocols) {
567567
if (protocol.startsWith(WS_PROTOCOL_ACTOR)) {
568-
actorId = protocol.substring(WS_PROTOCOL_ACTOR.length);
568+
actorId = decodeURIComponent(protocol.substring(WS_PROTOCOL_ACTOR.length));
569569
} else if (protocol.startsWith(WS_PROTOCOL_ENCODING)) {
570570
encoding = protocol.substring(
571571
WS_PROTOCOL_ENCODING.length,

0 commit comments

Comments
 (0)