feat: migrate protocol and HTTP to structured interface references
T-20: identify interfaces by exact scope/name pairs; add optional opaque scope_ref metadata and separate shape validation from path-dependent scope compatibility. Preserve call error precedence, strict JSON, validators and transport boundaries. Mechanically migrate consumers and document API/wire compatibility and deferred lifecycle semantics. Validation: cargo fmt --all --check; git diff --check; cargo check --workspace --all-targets; cargo test -p wip-protocol -p wip-http; cargo test --workspace (221 passing tests including doctests); cargo test --workspace --all-targets; nix develop --command cargo clippy --workspace --all-targets -- -D warnings; RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps. All pass. cargo/rustc 1.95.0; development-shell Clippy/rustc 1.97.1.
This commit is contained in:
@@ -98,6 +98,7 @@ fn real_listener_serves_three_core_interactions_and_write() {
|
||||
validator: file.validator.clone(),
|
||||
},
|
||||
interface: InterfaceTarget {
|
||||
scope_ref: None,
|
||||
reference: file.interfaces[0].clone(),
|
||||
validator: None,
|
||||
},
|
||||
@@ -141,6 +142,7 @@ fn real_listener_serves_three_core_interactions_and_write() {
|
||||
validator: file.validator,
|
||||
},
|
||||
interface: InterfaceTarget {
|
||||
scope_ref: None,
|
||||
reference: file.interfaces[1].clone(),
|
||||
validator: None,
|
||||
},
|
||||
@@ -412,7 +414,7 @@ fn call_argument_decoding_does_not_mask_missing_target() {
|
||||
let config = ServerConfig::for_root(temporary.path());
|
||||
let server = WipFsServer::new(config).expect("build server");
|
||||
let endpoint = Endpoint::parse("http://localhost/wip").expect("endpoint");
|
||||
let body = br#"{"target":{"path":"/missing"},"interface":{"reference":"unknown"},"operation":"missing","arguments":{"bytes":"not-base64"}}"#;
|
||||
let body = br#"{"target":{"path":"/missing"},"interface":{"reference":{"scope":"/","name":"unknown"}},"operation":"missing","arguments":{"bytes":"not-base64"}}"#;
|
||||
let request = http::Request::builder()
|
||||
.method(http::Method::POST)
|
||||
.uri(endpoint.route(Route::CallOperation).as_str())
|
||||
@@ -490,6 +492,7 @@ fn read_response_size_failure_is_transport_local() {
|
||||
validator: file.validator,
|
||||
},
|
||||
interface: InterfaceTarget {
|
||||
scope_ref: None,
|
||||
reference: file.interfaces[0].clone(),
|
||||
validator: None,
|
||||
},
|
||||
|
||||
@@ -576,7 +576,7 @@ fn observation_and_fetch_policy_panics_remain_sanitized_read_failures() {
|
||||
let mut registry = InterfaceRegistry::new();
|
||||
let defaults = DefaultInterfaces::register(&mut registry).unwrap();
|
||||
let custom = registry.register(MemoryOperationsDefinition, None).unwrap();
|
||||
let reference = custom.reference().as_str().to_owned();
|
||||
let reference = custom.reference().protocol_reference();
|
||||
let engine = Projection::new(
|
||||
MemoryBackend(fixture.shared.clone()),
|
||||
registry,
|
||||
@@ -616,8 +616,8 @@ type Engine = Projection<MemoryBackend, MemoryComposition, Policy>;
|
||||
struct Fixture {
|
||||
engine: Engine,
|
||||
shared: Arc<Shared>,
|
||||
custom: String,
|
||||
read: String,
|
||||
custom: wip_protocol::InterfaceReference,
|
||||
read: wip_protocol::InterfaceReference,
|
||||
limits: ResourceLimits,
|
||||
}
|
||||
impl Fixture {
|
||||
@@ -696,8 +696,8 @@ impl Fixture {
|
||||
limits,
|
||||
),
|
||||
shared,
|
||||
custom: custom_ref.as_str().into(),
|
||||
read: read_ref.as_str().into(),
|
||||
custom: custom_ref.protocol_reference(),
|
||||
read: read_ref.protocol_reference(),
|
||||
limits,
|
||||
}
|
||||
}
|
||||
@@ -707,7 +707,11 @@ impl Fixture {
|
||||
.observe(&ExecutionContext::new(), &observe_request(path, depth))
|
||||
.unwrap()
|
||||
}
|
||||
fn descriptor(&self, principal: &Principal, reference: &str) -> InterfaceDescriptor {
|
||||
fn descriptor(
|
||||
&self,
|
||||
principal: &Principal,
|
||||
reference: &wip_protocol::InterfaceReference,
|
||||
) -> InterfaceDescriptor {
|
||||
self.engine
|
||||
.view(principal)
|
||||
.fetch_interface(&fetch_request(reference))
|
||||
@@ -717,7 +721,7 @@ impl Fixture {
|
||||
fn request(
|
||||
&self,
|
||||
path: &str,
|
||||
reference: &str,
|
||||
reference: &wip_protocol::InterfaceReference,
|
||||
operation: &str,
|
||||
validator: Option<Vec<u8>>,
|
||||
) -> CallOperationRequest {
|
||||
@@ -727,7 +731,8 @@ impl Fixture {
|
||||
validator,
|
||||
},
|
||||
interface: InterfaceTarget {
|
||||
reference: reference.into(),
|
||||
scope_ref: None,
|
||||
reference: reference.clone(),
|
||||
validator: None,
|
||||
},
|
||||
operation: operation.into(),
|
||||
@@ -866,9 +871,9 @@ fn observe_request(path: &str, depth: u32) -> ObserveRequest {
|
||||
depth,
|
||||
}
|
||||
}
|
||||
fn fetch_request(reference: &str) -> FetchInterfaceRequest {
|
||||
fn fetch_request(reference: &wip_protocol::InterfaceReference) -> FetchInterfaceRequest {
|
||||
FetchInterfaceRequest {
|
||||
interface: reference.into(),
|
||||
interface: reference.clone(),
|
||||
}
|
||||
}
|
||||
fn success<T: std::fmt::Debug>(response: DecodedResponse<T>) -> T {
|
||||
@@ -1804,8 +1809,8 @@ fn policy_panics_and_guessed_operation_diagnostics_do_not_leak_to_http() {
|
||||
// This valid metadata names a nonexistent operation; bypass client-side
|
||||
// descriptor validation to exercise server diagnostics for untrusted names.
|
||||
let body = format!(
|
||||
r#"{{"target":{{"path":"/added"}},"interface":{{"reference":"{}"}},"operation":"{}","arguments":{{}}}}"#,
|
||||
fixture.custom, POLICY_SECRET
|
||||
r#"{{"target":{{"path":"/added"}},"interface":{{"reference":{{"scope":"{}","name":"{}"}}}},"operation":"{}","arguments":{{}}}}"#,
|
||||
fixture.custom.scope, fixture.custom.name, POLICY_SECRET
|
||||
);
|
||||
let request = http::Request::builder()
|
||||
.method(http::Method::POST)
|
||||
|
||||
Reference in New Issue
Block a user