Skip to main content

aws_smithy_http_server/schema/routing/
mod.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! Runtime construction and dispatch for the schema protocols a service declares.
7//!
8//! Routers implement either [`MetadataProtocolRouter`], which selects operations from the
9//! request URI, method and headers, or [`BodyProtocolRouter`], which can also inspect the
10//! complete body. Body routers receive only operations with no streaming input or output.
11//!
12//! Every service, including a single-protocol service, checks protocol claims. Routers
13//! are asked in the claim order resolved from
14//! [`ProtocolOrder`](crate::schema::protocol::ProtocolOrder) constraints. The built-in priority
15//! order and its wire compatibility implications are documented on
16//! [`ProtocolRegistry::BUILTIN`](crate::schema::protocol::ProtocolRegistry::BUILTIN).
17//! The first definite claim
18//! owns the request: it either identifies the operation or proceeds to routing, whose
19//! errors are terminal and serialized by that protocol.
20//! A [`RouteClaim::DeferredClaim`] offers an operation while later protocols try to
21//! claim definitively. If none does, the first deferred claim owns the request.
22//! A [`RouteClaim::DeferredRejection`] also lets later protocols try. If no definite
23//! or deferred claim succeeds, the first deferred rejection supplies the response;
24//! otherwise the service returns its protocol-neutral rejection.
25//!
26//! Each router can inspect the service's protocol IDs through
27//! [`RouterBuildContext::service_protocols`]. When both restJson1 and restXml are
28//! enabled, eligible requests without `Content-Type` offer deferred claims.
29//! If no protocol claims definitively, protocol priority selects restJson1.
30//!
31//! Enabling another protocol also changes identification of REST payload requests.
32//! A REST-only service accepts an untyped blob payload with an arbitrary or absent
33//! `Content-Type`. In a multi-protocol service, that payload claims REST through
34//! `application/octet-stream` (or its modeled `@mediaType`). A request such as
35//! `POST /upload` with `Content-Type: video/mp4`, or without a content type, can
36//! therefore receive the protocol-neutral `404` after another protocol is enabled.
37//! Payload requests do not offer the deferred claims used by eligible payload-less
38//! requests. Model the payload's media type or send its expected content type.
39//!
40//! Body routers first inspect the head with [`BodyProtocolRouter::claim`]. A
41//! [`BodyRouteClaim::ClaimedWithRoute`] dispatches without collecting the body.
42//! [`BodyRouteClaim::Claimed`] collects the body and calls [`BodyProtocolRouter::route_with_body`];
43//! [`BodyRouteClaim::NeedsBodyToClaim`] collects it and calls [`BodyProtocolRouter::claim_with_body`]
44//! first. Collection obeys the service's routing body limits. Collected bytes are reused
45//! by later routers if the claim is declined and replayed to the selected handler.
46//!
47//! Before collecting for `NeedsBodyToClaim`, the service checks metadata routers for a
48//! recognized streaming input, if its schema declares any. A match skips that body claim
49//! without retrying it. Recognition is cached for the request. Claims already made from
50//! the head retain their priority, including a body router's `Claimed` result.
51//!
52//! If every protocol declines and none supplies a deferred rejection, the service
53//! returns its protocol-neutral response, including for a single-protocol service:
54//! `404` with the XML body `<UnknownOperationException/>` followed by a newline and no
55//! `Content-Type` header.
56
57mod builder;
58mod protocol_router;
59pub mod route_errors;
60mod routers;
61mod routing_table;
62mod service;
63#[cfg(test)]
64mod test_helpers;
65#[cfg(test)]
66mod tests;
67
68pub use builder::MultiProtocolRoutingServiceBuilder;
69pub use protocol_router::{
70    BodyProtocolRouter, BodyRouteClaim, CollectedBody, MetadataProtocolRouter, OperationTarget, ProtocolOptions,
71    ProtocolResolutionError, RouteClaim, RouterBuildContext, RouterBuildError, SharedProtocolRouter,
72};
73pub use route_errors::{RoutingError, RoutingErrorKind};
74pub(crate) use routers::rpc_v2_cbor_router;
75pub use routers::{aws_json_router, rest_router};
76pub use service::{MultiProtocolRoutingFuture, MultiProtocolRoutingService};