diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt index a55cb4f23dd3ebc824f086451d5f3060567a5617..55cff80bc49fdab7a99ddc3b539e821360f1e887 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt @@ -135,8 +135,8 @@ class PythonApplicationGenerator( ) { rustBlockTemplate( """ - /// Dynamically codegenerate the routes, allowing to build the Smithy [#{SmithyServer}::Router]. - pub fn build_router(&mut self, event_loop: &#{pyo3}::PyAny) -> #{pyo3}::PyResult<#{SmithyServer}::Router> + /// Dynamically codegenerate the routes, allowing to build the Smithy [#{SmithyServer}::routing::Router]. + pub fn build_router(&mut self, event_loop: &#{pyo3}::PyAny) -> #{pyo3}::PyResult<#{SmithyServer}::routing::Router> """, *codegenScope, ) { @@ -162,7 +162,7 @@ class PythonApplicationGenerator( } rustTemplate( """ - let router: #{SmithyServer}::Router = router + let router: #{SmithyServer}::routing::Router = router .build() .expect("Unable to build operation registry") .into(); diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerServiceGenerator.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerServiceGenerator.kt index 58c87effbe7e4f00af0eb344ae6a0017e19972db..3798148cfd7d0ad265fefd564d2f8bf8871767c3 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerServiceGenerator.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerServiceGenerator.kt @@ -25,7 +25,7 @@ class PythonServerServiceGenerator( private val rustCrate: RustCrate, protocolGenerator: ProtocolGenerator, protocolSupport: ProtocolSupport, - protocol: ServerProtocol, + private val protocol: ServerProtocol, private val context: CoreCodegenContext, ) : ServerServiceGenerator(rustCrate, protocolGenerator, protocolSupport, protocol, context) { diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRuntimeType.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRuntimeType.kt index fa386b88871290792f9dae509fde619e1c34b638..3ae6c628226bfd6eae721f31c46aff66eb8ece12 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRuntimeType.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRuntimeType.kt @@ -39,8 +39,8 @@ object ServerRuntimeType { fun ResponseRejection(runtimeConfig: RuntimeConfig) = RuntimeType("ResponseRejection", ServerCargoDependency.SmithyHttpServer(runtimeConfig), "${runtimeConfig.crateSrcPrefix}_http_server::rejection") - fun Protocol(name: String, runtimeConfig: RuntimeConfig) = - RuntimeType(name, ServerCargoDependency.SmithyHttpServer(runtimeConfig), "${runtimeConfig.crateSrcPrefix}_http_server::protocols") + fun Protocol(name: String, path: String, runtimeConfig: RuntimeConfig) = + RuntimeType(name, ServerCargoDependency.SmithyHttpServer(runtimeConfig), "${runtimeConfig.crateSrcPrefix}_http_server::proto::" + path) - fun Protocol(runtimeConfig: RuntimeConfig) = Protocol("Protocol", runtimeConfig) + fun Protocol(runtimeConfig: RuntimeConfig) = Protocol("Protocol", "", runtimeConfig) } diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerServiceGeneratorV2.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerServiceGeneratorV2.kt index 3a5949c4d41a533748cd3beffd192a61ba1b57d5..64f09b7536c45380bc67ca3a612230a5876e6e46 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerServiceGeneratorV2.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/ServerServiceGeneratorV2.kt @@ -221,7 +221,7 @@ class ServerServiceGeneratorV2( { let router = #{Router:W}; $serviceName { - router: #{SmithyHttpServer}::routing::routers::RoutingService::new(router), + router: #{SmithyHttpServer}::routers::RoutingService::new(router), } } } @@ -280,7 +280,7 @@ class ServerServiceGeneratorV2( """ ##[derive(Clone)] pub struct $serviceName { - router: #{SmithyHttpServer}::routing::routers::RoutingService<#{Router}, #{Protocol}>, + router: #{SmithyHttpServer}::routers::RoutingService<#{Router}, #{Protocol}>, } impl $serviceName<()> { @@ -331,7 +331,7 @@ class ServerServiceGeneratorV2( { type Response = #{Http}::Response<#{SmithyHttpServer}::body::BoxBody>; type Error = S::Error; - type Future = #{SmithyHttpServer}::routing::routers::RoutingFuture; + type Future = #{SmithyHttpServer}::routers::RoutingFuture; fn poll_ready(&mut self, cx: &mut std::task::Context) -> std::task::Poll> { self.router.poll_ready(cx) diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/protocol/ServerProtocol.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/protocol/ServerProtocol.kt index bdd23431f662afddb1341aff444ee920bd0a2fc5..5c55e2c2b38bb904dfa34d6980d4047dae93784d 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/protocol/ServerProtocol.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/generators/protocol/ServerProtocol.kt @@ -97,18 +97,17 @@ class ServerAwsJsonProtocol( } override fun markerStruct(): RuntimeType { - val name = when (version) { + return when (version) { is AwsJsonVersion.Json10 -> { - "AwsJson10" + ServerRuntimeType.Protocol("AwsJson10", "aws_json_10", runtimeConfig) } is AwsJsonVersion.Json11 -> { - "AwsJson11" + ServerRuntimeType.Protocol("AwsJson11", "aws_json_11", runtimeConfig) } } - return ServerRuntimeType.Protocol(name, runtimeConfig) } - override fun routerType() = RuntimeType("AwsJsonRouter", ServerCargoDependency.SmithyHttpServer(runtimeConfig), "${runtimeConfig.crateSrcPrefix}_http_server::routing::routers::aws_json") + override fun routerType() = RuntimeType("AwsJsonRouter", ServerCargoDependency.SmithyHttpServer(runtimeConfig), "${runtimeConfig.crateSrcPrefix}_http_server::proto::aws_json::router") override fun routerConstruction(operationValues: Iterable): Writable = writable { val allOperationShapes = allOperations(coreCodegenContext) @@ -159,7 +158,7 @@ class ServerAwsJsonProtocol( } } -private fun restRouterType(runtimeConfig: RuntimeConfig) = RuntimeType("RestRouter", ServerCargoDependency.SmithyHttpServer(runtimeConfig), "${runtimeConfig.crateSrcPrefix}_http_server::routing::routers::rest") +private fun restRouterType(runtimeConfig: RuntimeConfig) = RuntimeType("RestRouter", ServerCargoDependency.SmithyHttpServer(runtimeConfig), "${runtimeConfig.crateSrcPrefix}_http_server::proto::rest::router") private fun restRouterConstruction( protocol: ServerProtocol, @@ -169,8 +168,8 @@ private fun restRouterConstruction( val operations = allOperations(coreCodegenContext) // TODO(https://github.com/awslabs/smithy-rs/issues/1724#issue-1367509999): This causes a panic: "symbol visitor - // should not be invoked in service shapes" - // val serviceName = symbolProvider.toSymbol(service).name + // should not be invoked in service shapes" + // val serviceName = symbolProvider.toSymbol(service).name val serviceName = coreCodegenContext.serviceShape.id.name val pairs = writable { for ((operationShape, operationValue) in operations.zip(operationValues)) { @@ -212,7 +211,7 @@ class ServerRestJsonProtocol( fun fromCoreProtocol(restJson: RestJson): ServerRestJsonProtocol = ServerRestJsonProtocol(restJson.coreCodegenContext) } - override fun markerStruct() = ServerRuntimeType.Protocol("AwsRestJson1", runtimeConfig) + override fun markerStruct() = ServerRuntimeType.Protocol("AwsRestJson1", "rest_json_1", runtimeConfig) override fun routerType() = restRouterType(runtimeConfig) @@ -241,7 +240,7 @@ class ServerRestXmlProtocol( } } - override fun markerStruct() = ServerRuntimeType.Protocol("AwsRestXml", runtimeConfig) + override fun markerStruct() = ServerRuntimeType.Protocol("AwsRestXml", "rest_xml", runtimeConfig) override fun routerType() = restRouterType(runtimeConfig) diff --git a/rust-runtime/aws-smithy-http-server-python/src/server.rs b/rust-runtime/aws-smithy-http-server-python/src/server.rs index 7eacb154cc6675df2df40eca166227509d3e357a..3f1dac23cef5c37bc184acbd0455be1fff0af6a2 100644 --- a/rust-runtime/aws-smithy-http-server-python/src/server.rs +++ b/rust-runtime/aws-smithy-http-server-python/src/server.rs @@ -6,7 +6,7 @@ use std::{collections::HashMap, ops::Deref, process, thread}; -use aws_smithy_http_server::{AddExtensionLayer, Router}; +use aws_smithy_http_server::{routing::Router, AddExtensionLayer}; use parking_lot::Mutex; use pyo3::{prelude::*, types::IntoPyDict}; use signal_hook::{consts::*, iterator::Signals}; @@ -188,7 +188,7 @@ event_loop.add_signal_handler(signal.SIGINT, /// [configure_python_event_loop](#method.configure_python_event_loop) to properly setup it up. /// /// We retrieve the Python context object, if setup by the user calling [PyApp::context] method, - /// generate the state structure and build the [aws_smithy_http_server::Router], filling + /// generate the state structure and build the [aws_smithy_http_server::routing::Router], filling /// it with the functions generated by `PythonServerOperationHandlerGenerator.kt`. /// At last we get a cloned reference to the underlying [socket2::Socket]. /// @@ -334,7 +334,7 @@ event_loop.add_signal_handler(signal.SIGINT, /// pub struct App {}; /// /// impl App { - /// pub fn build_router(&mut self, event_loop: &PyAny) -> PyResult { todo!() } + /// pub fn build_router(&mut self, event_loop: &PyAny) -> PyResult { todo!() } /// } /// /// impl PyApp for App { diff --git a/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/bin/pokemon-service-tls.rs b/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/bin/pokemon-service-tls.rs index 84ad477ff8ec37b05081cc08da8eefcca0df89bc..026d0a0ce4c0ce6f621013966f27f45e4548da49 100644 --- a/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/bin/pokemon-service-tls.rs +++ b/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/bin/pokemon-service-tls.rs @@ -28,7 +28,7 @@ use std::io::BufReader; use std::net::SocketAddr; use std::sync::Arc; -use aws_smithy_http_server::{AddExtensionLayer, Router}; +use aws_smithy_http_server::{routing::Router, AddExtensionLayer}; use clap::Parser; use futures_util::stream::StreamExt; use pokemon_service::{ diff --git a/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/lambda.rs b/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/lambda.rs index a286b62e8f5dc7119079b0dfe91a1cad6b32a514..8b6f579dcc5debeacf65610b6f5256189e223ee6 100644 --- a/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/lambda.rs +++ b/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/lambda.rs @@ -6,7 +6,7 @@ // This program is exported as a binary named `pokemon-service-lambda`. use std::sync::Arc; -use aws_smithy_http_server::{routing::LambdaHandler, AddExtensionLayer, Router}; +use aws_smithy_http_server::{routing::LambdaHandler, routing::Router, AddExtensionLayer}; use pokemon_service::{ capture_pokemon, empty_operation, get_pokemon_species, get_server_statistics, get_storage, health_check_operation, setup_tracing, State, diff --git a/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/main.rs b/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/main.rs index 6d03d4cf2c4d8765960b1ce2c40a367584be4e72..67c8e90889086a56e92cb6ca094cf0e79fbd559f 100644 --- a/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/main.rs +++ b/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/main.rs @@ -6,7 +6,7 @@ // This program is exported as a binary named `pokemon-service`. use std::{net::SocketAddr, sync::Arc}; -use aws_smithy_http_server::{AddExtensionLayer, Router}; +use aws_smithy_http_server::{routing::Router, AddExtensionLayer}; use clap::Parser; use pokemon_service::{ capture_pokemon, empty_operation, get_pokemon_species, get_server_statistics, get_storage, health_check_operation, diff --git a/rust-runtime/aws-smithy-http-server/src/lib.rs b/rust-runtime/aws-smithy-http-server/src/lib.rs index 842b5cfdfdfa6ee58c4d810a3b780bd7f04bd9fb..6e34fb1d093e89297196df49d9326ecc5a26267c 100644 --- a/rust-runtime/aws-smithy-http-server/src/lib.rs +++ b/rust-runtime/aws-smithy-http-server/src/lib.rs @@ -31,13 +31,17 @@ pub mod routing; #[doc(hidden)] pub mod runtime_error; +#[doc(hidden)] +pub mod routers; + #[doc(inline)] pub(crate) use self::error::Error; pub use self::extension::Extension; #[doc(inline)] -pub use self::routing::Router; -#[doc(inline)] pub use tower_http::add_extension::{AddExtension, AddExtensionLayer}; #[cfg(test)] mod test_helpers; + +#[doc(hidden)] +pub mod proto; diff --git a/rust-runtime/aws-smithy-http-server/src/proto/aws_json/mod.rs b/rust-runtime/aws-smithy-http-server/src/proto/aws_json/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..a579436e91b91f7c7c9cbb17c88857060fa325ad --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/proto/aws_json/mod.rs @@ -0,0 +1,6 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +pub mod router; diff --git a/rust-runtime/aws-smithy-http-server/src/routing/routers/aws_json.rs b/rust-runtime/aws-smithy-http-server/src/proto/aws_json/router.rs similarity index 67% rename from rust-runtime/aws-smithy-http-server/src/routing/routers/aws_json.rs rename to rust-runtime/aws-smithy-http-server/src/proto/aws_json/router.rs index eb83d0c178e8f26c0d35da6c840746a760a6baf8..67041a62fc970a16082bb26c21bbf22d814cab33 100644 --- a/rust-runtime/aws-smithy-http-server/src/routing/routers/aws_json.rs +++ b/rust-runtime/aws-smithy-http-server/src/proto/aws_json/router.rs @@ -5,19 +5,16 @@ use std::convert::Infallible; -use http::header::ToStrError; -use thiserror::Error; -use tower::{Layer, Service}; +use tower::Layer; +use tower::Service; -use crate::{ - body::{empty, BoxBody}, - extension::RuntimeErrorExtension, - protocols::{AwsJson10, AwsJson11}, - response::IntoResponse, - routing::{tiny_map::TinyMap, Route}, -}; +use crate::body::BoxBody; +use crate::routers::Router; +use crate::routing::tiny_map::TinyMap; +use crate::routing::Route; -use super::Router; +use http::header::ToStrError; +use thiserror::Error; /// An AWS JSON routing error. #[derive(Debug, Error)] @@ -39,38 +36,6 @@ pub enum Error { NotFound, } -impl IntoResponse for Error { - fn into_response(self) -> http::Response { - match self { - Error::MethodNotAllowed => super::method_disallowed(), - _ => http::Response::builder() - .status(http::StatusCode::NOT_FOUND) - .header(http::header::CONTENT_TYPE, "application/x-amz-json-1.0") - .extension(RuntimeErrorExtension::new( - super::UNKNOWN_OPERATION_EXCEPTION.to_string(), - )) - .body(empty()) - .expect("invalid HTTP response for AWS JSON routing error; please file a bug report under https://github.com/awslabs/smithy-rs/issues"), - } - } -} - -impl IntoResponse for Error { - fn into_response(self) -> http::Response { - match self { - Error::MethodNotAllowed => super::method_disallowed(), - _ => http::Response::builder() - .status(http::StatusCode::NOT_FOUND) - .header(http::header::CONTENT_TYPE, "application/x-amz-json-1.1") - .extension(RuntimeErrorExtension::new( - super::UNKNOWN_OPERATION_EXCEPTION.to_string(), - )) - .body(empty()) - .expect("invalid HTTP response for AWS JSON routing error; please file a bug report under https://github.com/awslabs/smithy-rs/issues"), - } - } -} - // This constant determines when the `TinyMap` implementation switches from being a `Vec` to a // `HashMap`. This is chosen to be 15 as a result of the discussion around // https://github.com/awslabs/smithy-rs/pull/1429#issuecomment-1147516546 diff --git a/rust-runtime/aws-smithy-http-server/src/proto/aws_json_10/mod.rs b/rust-runtime/aws-smithy-http-server/src/proto/aws_json_10/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..183aaf81194cef3b6231208fbf0ce0ae9ccf9e8d --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/proto/aws_json_10/mod.rs @@ -0,0 +1,9 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +pub mod router; + +/// [AWS JSON 1.0 Protocol](https://awslabs.github.io/smithy/2.0/aws/protocols/aws-json-1_0-protocol.html). +pub struct AwsJson10; diff --git a/rust-runtime/aws-smithy-http-server/src/proto/aws_json_10/router.rs b/rust-runtime/aws-smithy-http-server/src/proto/aws_json_10/router.rs new file mode 100644 index 0000000000000000000000000000000000000000..e6805dc769c9abe229698ea8e5a60ee9b0de7788 --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/proto/aws_json_10/router.rs @@ -0,0 +1,30 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +use crate::body::{empty, BoxBody}; +use crate::extension::RuntimeErrorExtension; +use crate::proto::aws_json::router::Error; +use crate::response::IntoResponse; +use crate::routers::{method_disallowed, UNKNOWN_OPERATION_EXCEPTION}; + +use super::AwsJson10; + +pub use crate::proto::aws_json::router::*; + +impl IntoResponse for Error { + fn into_response(self) -> http::Response { + match self { + Error::MethodNotAllowed => method_disallowed(), + _ => http::Response::builder() + .status(http::StatusCode::NOT_FOUND) + .header(http::header::CONTENT_TYPE, "application/x-amz-json-1.0") + .extension(RuntimeErrorExtension::new( + UNKNOWN_OPERATION_EXCEPTION.to_string(), + )) + .body(empty()) + .expect("invalid HTTP response for AWS JSON routing error; please file a bug report under https://github.com/awslabs/smithy-rs/issues"), + } + } +} diff --git a/rust-runtime/aws-smithy-http-server/src/proto/aws_json_11/mod.rs b/rust-runtime/aws-smithy-http-server/src/proto/aws_json_11/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..3bc1f75c61cbe11687c781ce21702ee563edc6ba --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/proto/aws_json_11/mod.rs @@ -0,0 +1,9 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +pub mod router; + +/// [AWS JSON 1.1 Protocol](https://awslabs.github.io/smithy/2.0/aws/protocols/aws-json-1_1-protocol.html). +pub struct AwsJson11; diff --git a/rust-runtime/aws-smithy-http-server/src/proto/aws_json_11/router.rs b/rust-runtime/aws-smithy-http-server/src/proto/aws_json_11/router.rs new file mode 100644 index 0000000000000000000000000000000000000000..dcd1cace6a43a7aff971c66dd9b3ebfac212ca73 --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/proto/aws_json_11/router.rs @@ -0,0 +1,30 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +use crate::body::{empty, BoxBody}; +use crate::extension::RuntimeErrorExtension; +use crate::proto::aws_json::router::Error; +use crate::response::IntoResponse; +use crate::routers::{method_disallowed, UNKNOWN_OPERATION_EXCEPTION}; + +use super::AwsJson11; + +pub use crate::proto::aws_json::router::*; + +impl IntoResponse for Error { + fn into_response(self) -> http::Response { + match self { + Error::MethodNotAllowed => method_disallowed(), + _ => http::Response::builder() + .status(http::StatusCode::NOT_FOUND) + .header(http::header::CONTENT_TYPE, "application/x-amz-json-1.1") + .extension(RuntimeErrorExtension::new( + UNKNOWN_OPERATION_EXCEPTION.to_string(), + )) + .body(empty()) + .expect("invalid HTTP response for AWS JSON routing error; please file a bug report under https://github.com/awslabs/smithy-rs/issues"), + } + } +} diff --git a/rust-runtime/aws-smithy-http-server/src/proto/mod.rs b/rust-runtime/aws-smithy-http-server/src/proto/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..39344ab4f1dedcc05bce747d6726ef624a3f7bc8 --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/proto/mod.rs @@ -0,0 +1,11 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +pub mod aws_json; +pub mod aws_json_10; +pub mod aws_json_11; +pub mod rest; +pub mod rest_json_1; +pub mod rest_xml; diff --git a/rust-runtime/aws-smithy-http-server/src/proto/rest/mod.rs b/rust-runtime/aws-smithy-http-server/src/proto/rest/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..a579436e91b91f7c7c9cbb17c88857060fa325ad --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/proto/rest/mod.rs @@ -0,0 +1,6 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +pub mod router; diff --git a/rust-runtime/aws-smithy-http-server/src/routing/routers/rest.rs b/rust-runtime/aws-smithy-http-server/src/proto/rest/router.rs similarity index 63% rename from rust-runtime/aws-smithy-http-server/src/routing/routers/rest.rs rename to rust-runtime/aws-smithy-http-server/src/proto/rest/router.rs index 53d16de55f69cd1ba828ae62dfaa43e70dba829b..4c73eda72bf18d7511cf3a398699c028863445b2 100644 --- a/rust-runtime/aws-smithy-http-server/src/routing/routers/rest.rs +++ b/rust-runtime/aws-smithy-http-server/src/proto/rest/router.rs @@ -5,21 +5,15 @@ use std::convert::Infallible; -use thiserror::Error; -use tower::{Layer, Service}; - -use crate::{ - body::{empty, BoxBody}, - extension::RuntimeErrorExtension, - protocols::{AwsRestJson1, AwsRestXml}, - response::IntoResponse, - routing::{ - request_spec::{Match, RequestSpec}, - Route, - }, -}; +use crate::body::BoxBody; +use crate::routers::Router; +use crate::routing::request_spec::Match; +use crate::routing::request_spec::RequestSpec; +use crate::routing::Route; +use tower::Layer; +use tower::Service; -use super::Router; +use thiserror::Error; /// An AWS REST routing error. #[derive(Debug, Error)] @@ -32,39 +26,6 @@ pub enum Error { MethodNotAllowed, } -impl IntoResponse for Error { - fn into_response(self) -> http::Response { - match self { - Error::NotFound => http::Response::builder() - .status(http::StatusCode::NOT_FOUND) - .header(http::header::CONTENT_TYPE, "application/json") - .header("X-Amzn-Errortype", super::UNKNOWN_OPERATION_EXCEPTION) - .extension(RuntimeErrorExtension::new( - super::UNKNOWN_OPERATION_EXCEPTION.to_string(), - )) - .body(crate::body::to_boxed("{}")) - .expect("invalid HTTP response for REST JSON routing error; please file a bug report under https://github.com/awslabs/smithy-rs/issues"), - Error::MethodNotAllowed => super::method_disallowed(), - } - } -} - -impl IntoResponse for Error { - fn into_response(self) -> http::Response { - match self { - Error::NotFound => http::Response::builder() - .status(http::StatusCode::NOT_FOUND) - .header(http::header::CONTENT_TYPE, "application/xml") - .extension(RuntimeErrorExtension::new( - super::UNKNOWN_OPERATION_EXCEPTION.to_string(), - )) - .body(empty()) - .expect("invalid HTTP response for REST JSON routing error; please file a bug report under https://github.com/awslabs/smithy-rs/issues"), - Error::MethodNotAllowed => super::method_disallowed(), - } - } -} - /// A [`Router`] supporting [`AWS REST JSON 1.0`] and [`AWS REST XML`] protocols. /// /// [AWS REST JSON 1.0]: https://awslabs.github.io/smithy/2.0/aws/protocols/aws-restjson1-protocol.html diff --git a/rust-runtime/aws-smithy-http-server/src/proto/rest_json_1/mod.rs b/rust-runtime/aws-smithy-http-server/src/proto/rest_json_1/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..f0bd51ec3f69bb2f6dc5ef72dc0cd46d5b7a9adb --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/proto/rest_json_1/mod.rs @@ -0,0 +1,9 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +pub mod router; + +/// [AWS REST JSON 1.0 Protocol](https://awslabs.github.io/smithy/2.0/aws/protocols/aws-restjson1-protocol.html). +pub struct AwsRestJson1; diff --git a/rust-runtime/aws-smithy-http-server/src/proto/rest_json_1/router.rs b/rust-runtime/aws-smithy-http-server/src/proto/rest_json_1/router.rs new file mode 100644 index 0000000000000000000000000000000000000000..8f37efbfe58096a7539915ba24a2f9b879ef1f9d --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/proto/rest_json_1/router.rs @@ -0,0 +1,31 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +use crate::body::BoxBody; +use crate::extension::RuntimeErrorExtension; +use crate::proto::rest::router::Error; +use crate::response::IntoResponse; +use crate::routers::{method_disallowed, UNKNOWN_OPERATION_EXCEPTION}; + +use super::AwsRestJson1; + +pub use crate::proto::rest::router::*; + +impl IntoResponse for Error { + fn into_response(self) -> http::Response { + match self { + Error::NotFound => http::Response::builder() + .status(http::StatusCode::NOT_FOUND) + .header(http::header::CONTENT_TYPE, "application/json") + .header("X-Amzn-Errortype", UNKNOWN_OPERATION_EXCEPTION) + .extension(RuntimeErrorExtension::new( + UNKNOWN_OPERATION_EXCEPTION.to_string(), + )) + .body(crate::body::to_boxed("{}")) + .expect("invalid HTTP response for REST JSON routing error; please file a bug report under https://github.com/awslabs/smithy-rs/issues"), + Error::MethodNotAllowed => method_disallowed(), + } + } +} diff --git a/rust-runtime/aws-smithy-http-server/src/proto/rest_xml/mod.rs b/rust-runtime/aws-smithy-http-server/src/proto/rest_xml/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..42eadb468f658a1025df34c2f465e50ebbaf46eb --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/proto/rest_xml/mod.rs @@ -0,0 +1,9 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +pub mod router; + +/// [AWS REST XML Protocol](https://awslabs.github.io/smithy/2.0/aws/protocols/aws-restxml-protocol.html). +pub struct AwsRestXml; diff --git a/rust-runtime/aws-smithy-http-server/src/proto/rest_xml/router.rs b/rust-runtime/aws-smithy-http-server/src/proto/rest_xml/router.rs new file mode 100644 index 0000000000000000000000000000000000000000..6ef812a25ef0bf7997ad2629a7dfb755b2aa240c --- /dev/null +++ b/rust-runtime/aws-smithy-http-server/src/proto/rest_xml/router.rs @@ -0,0 +1,33 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +use crate::body::empty; +use crate::body::BoxBody; +use crate::extension::RuntimeErrorExtension; +use crate::proto::rest::router::Error; +use crate::response::IntoResponse; +use crate::routers::method_disallowed; +use crate::routers::UNKNOWN_OPERATION_EXCEPTION; + +use super::AwsRestXml; + +pub use crate::proto::rest::router::*; + +/// An AWS REST routing error. +impl IntoResponse for Error { + fn into_response(self) -> http::Response { + match self { + Error::NotFound => http::Response::builder() + .status(http::StatusCode::NOT_FOUND) + .header(http::header::CONTENT_TYPE, "application/xml") + .extension(RuntimeErrorExtension::new( + UNKNOWN_OPERATION_EXCEPTION.to_string(), + )) + .body(empty()) + .expect("invalid HTTP response for REST JSON routing error; please file a bug report under https://github.com/awslabs/smithy-rs/issues"), + Error::MethodNotAllowed => method_disallowed(), + } + } +} diff --git a/rust-runtime/aws-smithy-http-server/src/protocols.rs b/rust-runtime/aws-smithy-http-server/src/protocols.rs index 7bbf8068941de6e93f763b02b2e35bc44e0817c9..1707e33cf7848895e4324ee3cc72beffc119dc44 100644 --- a/rust-runtime/aws-smithy-http-server/src/protocols.rs +++ b/rust-runtime/aws-smithy-http-server/src/protocols.rs @@ -7,18 +7,6 @@ use crate::rejection::MissingContentTypeReason; use crate::request::RequestParts; -/// [AWS REST JSON 1.0 Protocol](https://awslabs.github.io/smithy/2.0/aws/protocols/aws-restjson1-protocol.html). -pub struct AwsRestJson1; - -/// [AWS REST XML Protocol](https://awslabs.github.io/smithy/2.0/aws/protocols/aws-restxml-protocol.html). -pub struct AwsRestXml; - -/// [AWS JSON 1.0 Protocol](https://awslabs.github.io/smithy/2.0/aws/protocols/aws-json-1_0-protocol.html). -pub struct AwsJson10; - -/// [AWS JSON 1.1 Protocol](https://awslabs.github.io/smithy/2.0/aws/protocols/aws-json-1_1-protocol.html). -pub struct AwsJson11; - /// Supported protocols. #[derive(Debug, Clone, Copy, PartialEq)] pub enum Protocol { diff --git a/rust-runtime/aws-smithy-http-server/src/routing/routers/mod.rs b/rust-runtime/aws-smithy-http-server/src/routers/mod.rs similarity index 96% rename from rust-runtime/aws-smithy-http-server/src/routing/routers/mod.rs rename to rust-runtime/aws-smithy-http-server/src/routers/mod.rs index e70fe1abdf861ff286163c1ff7f694ae48310337..abefe0ba32d0264d4f6ab198e1e529c271927065 100644 --- a/rust-runtime/aws-smithy-http-server/src/routing/routers/mod.rs +++ b/rust-runtime/aws-smithy-http-server/src/routers/mod.rs @@ -28,13 +28,10 @@ use crate::{ response::IntoResponse, }; -pub mod aws_json; -pub mod rest; - -const UNKNOWN_OPERATION_EXCEPTION: &str = "UnknownOperationException"; +pub(crate) const UNKNOWN_OPERATION_EXCEPTION: &str = "UnknownOperationException"; /// Constructs common response to method disallowed. -fn method_disallowed() -> http::Response { +pub(crate) fn method_disallowed() -> http::Response { let mut responses = http::Response::default(); *responses.status_mut() = http::StatusCode::METHOD_NOT_ALLOWED; responses diff --git a/rust-runtime/aws-smithy-http-server/src/routing/future.rs b/rust-runtime/aws-smithy-http-server/src/routing/future.rs index 95d4cbcf5f85a896451d479c16cd55958e204867..c6f0657c437f49c1a7e5f2f4ccae2f7746bd70be 100644 --- a/rust-runtime/aws-smithy-http-server/src/routing/future.rs +++ b/rust-runtime/aws-smithy-http-server/src/routing/future.rs @@ -34,10 +34,12 @@ //! Future types. +use crate::routers::RoutingFuture; + use super::Route; pub use super::{into_make_service::IntoMakeService, route::RouteFuture}; opaque_future! { /// Response future for [`Router`](super::Router). - pub type RouterFuture = super::routers::RoutingFuture, B>; + pub type RouterFuture = RoutingFuture, B>; } diff --git a/rust-runtime/aws-smithy-http-server/src/routing/mod.rs b/rust-runtime/aws-smithy-http-server/src/routing/mod.rs index 3e8a67c9c18d25c194ff7618da98b3216425cff4..e72f04f30d0c03cff405ea90f4181a8f14d6c32f 100644 --- a/rust-runtime/aws-smithy-http-server/src/routing/mod.rs +++ b/rust-runtime/aws-smithy-http-server/src/routing/mod.rs @@ -13,10 +13,14 @@ use std::{ }; use self::request_spec::RequestSpec; -use self::routers::{aws_json::AwsJsonRouter, rest::RestRouter, RoutingService}; -use crate::body::{boxed, Body, BoxBody, HttpBody}; -use crate::error::BoxError; -use crate::protocols::{AwsJson10, AwsJson11, AwsRestJson1, AwsRestXml}; +use crate::{ + body::{boxed, Body, BoxBody, HttpBody}, + proto::{ + aws_json::router::AwsJsonRouter, aws_json_10::AwsJson10, aws_json_11::AwsJson11, rest::router::RestRouter, + rest_json_1::AwsRestJson1, rest_xml::AwsRestXml, + }, +}; +use crate::{error::BoxError, routers::RoutingService}; use http::{Request, Response}; use tower::layer::Layer; @@ -31,9 +35,8 @@ mod lambda_handler; pub mod request_spec; mod route; -#[doc(hidden)] -pub mod routers; -mod tiny_map; + +pub(crate) mod tiny_map; pub use self::lambda_handler::LambdaHandler; pub use self::{future::RouterFuture, into_make_service::IntoMakeService, route::Route}; diff --git a/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs b/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs index 5e503058861b6f61ea8d4e1d232b35b73c422b72..e1f8e4740ac1563e4c011435aa1d97515c308374 100644 --- a/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs +++ b/rust-runtime/aws-smithy-http-server/src/routing/request_spec.rs @@ -85,7 +85,7 @@ pub struct RequestSpec { } #[derive(Debug, PartialEq)] -pub(super) enum Match { +pub(crate) enum Match { /// The request matches the URI pattern spec. Yes, /// The request matches the URI pattern spec, but the wrong HTTP method was used. `405 Method @@ -158,11 +158,11 @@ impl RequestSpec { /// updates the spec to define the behavior, update our implementation. /// /// [the TypeScript sSDK is implementing]: https://github.com/awslabs/smithy-typescript/blob/d263078b81485a6a2013d243639c0c680343ff47/smithy-typescript-ssdk-libs/server-common/src/httpbinding/mux.ts#L59. - pub(super) fn rank(&self) -> usize { + pub(crate) fn rank(&self) -> usize { self.uri_spec.path_and_query.path_segments.0.len() + self.uri_spec.path_and_query.query_segments.0.len() } - pub(super) fn matches(&self, req: &Request) -> Match { + pub(crate) fn matches(&self, req: &Request) -> Match { if let Some(_host_prefix) = &self.uri_spec.host_prefix { todo!("Look at host prefix"); } diff --git a/rust-runtime/aws-smithy-http-server/src/runtime_error.rs b/rust-runtime/aws-smithy-http-server/src/runtime_error.rs index f86b6df6b4aedeaa9ebb16c4e206b556b5458857..b8a4e71e0aa62924815dc62e25c66311018d51df 100644 --- a/rust-runtime/aws-smithy-http-server/src/runtime_error.rs +++ b/rust-runtime/aws-smithy-http-server/src/runtime_error.rs @@ -21,10 +21,12 @@ //! and converts into the corresponding `RuntimeError`, and then it uses the its //! [`RuntimeError::into_response`] method to render and send a response. -use crate::{ - protocols::{AwsJson10, AwsJson11, AwsRestJson1, AwsRestXml, Protocol}, - response::{IntoResponse, Response}, -}; +use crate::proto::aws_json_10::AwsJson10; +use crate::proto::aws_json_11::AwsJson11; +use crate::proto::rest_json_1::AwsRestJson1; +use crate::proto::rest_xml::AwsRestXml; +use crate::protocols::Protocol; +use crate::response::{IntoResponse, Response}; #[derive(Debug)] pub enum RuntimeErrorKind {