fix: preserve generated runtime request boundaries

This commit is contained in:
2026-09-23 11:08:54 +09:00
parent 515a19bbc3
commit f25c8d8b6d
4 changed files with 42 additions and 18 deletions
+8 -9
View File
@@ -448,16 +448,15 @@ mod tests {
let base_url = format!("http://{address}"); let base_url = format!("http://{address}");
let identity = RuntimeIdentityMaterial::generate("runtime-test").unwrap(); let identity = RuntimeIdentityMaterial::generate("runtime-test").unwrap();
let handle = handle_for(b"archive-bytes"); let handle = handle_for(b"archive-bytes");
let client = HttpBackendResourceClient::new(format!("{base_url}/fetch"), None) let client = HttpBackendResourceClient::new(
.with_request_timeout(std::time::Duration::from_millis(25)) format!("{base_url}/api/runtime/v1/workspaces/workspace-test/resources/fetch"),
.with_workspace_request_client( None,
RuntimeWorkspaceRequestClient::new( )
"workspace-test", .with_request_timeout(std::time::Duration::from_millis(25))
base_url.clone(), .with_workspace_request_client(
"runtime-test", RuntimeWorkspaceRequestClient::new("workspace-test", base_url.clone(), "runtime-test")
)
.with_runtime_request_source(&identity, base_url), .with_runtime_request_source(&identity, base_url),
); );
let error = client let error = client
.fetch_resource(BackendResourceFetchRequest { .fetch_resource(BackendResourceFetchRequest {
+17 -8
View File
@@ -1070,9 +1070,12 @@ mod tests {
server.join().unwrap(); server.join().unwrap();
let request = received.lock().unwrap().clone(); let request = received.lock().unwrap().clone();
assert!(request.contains( assert!(
"GET /api/w/workspace-a/worker-discovery/workers?limit=1&cursor=v1%3A0&query=coder%20two " request.contains(
)); "GET /api/w/workspace-a/worker-discovery/workers?cursor=v1%3A0&limit=1&query=coder+two "
),
"unexpected discovery request: {request}"
);
let token = request let token = request
.lines() .lines()
.find_map(|line| { .find_map(|line| {
@@ -1086,7 +1089,7 @@ mod tests {
assert_eq!(claims.permission, WORKSPACE_WORKER_DISCOVERY_PERMISSION); assert_eq!(claims.permission, WORKSPACE_WORKER_DISCOVERY_PERMISSION);
assert_eq!( assert_eq!(
claims.path, claims.path,
"/api/w/workspace-a/worker-discovery/workers?limit=1&cursor=v1%3A0&query=coder%20two" "/api/w/workspace-a/worker-discovery/workers?cursor=v1%3A0&limit=1&query=coder+two"
); );
} }
@@ -1145,9 +1148,15 @@ mod tests {
let count = stream.read(&mut bytes).unwrap(); let count = stream.read(&mut bytes).unwrap();
*received_for_server.lock().unwrap() = *received_for_server.lock().unwrap() =
String::from_utf8_lossy(&bytes[..count]).into_owned(); String::from_utf8_lossy(&bytes[..count]).into_owned();
stream let body =
.write_all(b"HTTP/1.1 204 No Content\r\nContent-Length: 0\r\n\r\n") r#"{"removed":true,"runtime_id":"runtime-target","worker_id":"worker-target"}"#;
.unwrap(); write!(
stream,
"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: {}\r\n\r\n{}",
body.len(),
body
)
.unwrap();
}); });
let identity = RuntimeIdentityMaterial::generate("runtime-a").unwrap(); let identity = RuntimeIdentityMaterial::generate("runtime-a").unwrap();
@@ -1166,7 +1175,7 @@ mod tests {
let response = forwarder let response = forwarder
.execute_worker_remove("runtime-target", "worker-target", "retire obsolete Worker") .execute_worker_remove("runtime-target", "worker-target", "retire obsolete Worker")
.unwrap(); .unwrap();
assert_eq!(response.status, 204); assert_eq!(response.status, 200);
server.join().unwrap(); server.join().unwrap();
let request = received.lock().unwrap().clone(); let request = received.lock().unwrap().clone();
+14
View File
@@ -583,10 +583,24 @@ fn workspace_server_json_request<T: serde::Serialize>(
)) ))
} }
fn encode_workspace_path_segment(value: &str) -> String {
let mut encoded = String::with_capacity(value.len());
for byte in value.bytes() {
if byte.is_ascii_alphanumeric() || matches!(byte, b'-' | b'_' | b'.' | b'~') {
encoded.push(byte as char);
} else {
use std::fmt::Write as _;
let _ = write!(encoded, "%{byte:02X}");
}
}
encoded
}
fn workspace_server_operation_request( fn workspace_server_operation_request(
workspace_id: &str, workspace_id: &str,
operation: WorkspaceServerOperation, operation: WorkspaceServerOperation,
) -> Result<WorkspaceRequest, WorkspaceClientError> { ) -> Result<WorkspaceRequest, WorkspaceClientError> {
let workspace_id = encode_workspace_path_segment(workspace_id);
let base = format!("/api/w/{workspace_id}"); let base = format!("/api/w/{workspace_id}");
match operation { match operation {
WorkspaceServerOperation::WorkerControlList => Ok(WorkspaceRequest::get(format!( WorkspaceServerOperation::WorkerControlList => Ok(WorkspaceRequest::get(format!(
+3 -1
View File
@@ -115,7 +115,9 @@ use worker_runtime::http_server::{
RUNTIME_HTTP_PROTOCOL_MAX_VERSION, RUNTIME_HTTP_PROTOCOL_MIN_VERSION, RUNTIME_HTTP_PROTOCOL_MAX_VERSION, RUNTIME_HTTP_PROTOCOL_MIN_VERSION,
RUNTIME_HTTP_PROTOCOL_VERSION, RUNTIME_HTTP_PROTOCOL_VERSION,
}; };
use worker_runtime::resource::{BackendResourceError, BackendResourceFetchRequest}; #[cfg(test)]
use worker_runtime::resource::BackendResourceError;
use worker_runtime::resource::BackendResourceFetchRequest;
use worker_runtime::worker_backend::{ProfileRuntimeWorkerFactory, WorkerRuntimeExecutionBackend}; use worker_runtime::worker_backend::{ProfileRuntimeWorkerFactory, WorkerRuntimeExecutionBackend};
use worker_runtime::workspace_issuer::{ use worker_runtime::workspace_issuer::{
WORKSPACE_VERIFICATION_ACK_PATH, WORKSPACE_VERIFICATION_CHALLENGE_PATH, WORKSPACE_VERIFICATION_ACK_PATH, WORKSPACE_VERIFICATION_CHALLENGE_PATH,