Skip to content

File tree

3 files changed

+86
-1
lines changed

3 files changed

+86
-1
lines changed

rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub async fn run_lambda() {
5757
.layer(AddExtensionLayer::new(shared_state)),
5858
);
5959

60-
let lambda = lambda_http::run(app);
60+
let lambda = lambda_http::run(app.into_make_lambda_service());
6161

6262
if let Err(err) = lambda.await {
6363
eprintln!("lambda error: {}", err);
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0.
4+
*/
5+
6+
use http::uri;
7+
use lambda_http::{Request, RequestExt};
8+
use std::{
9+
fmt::Debug,
10+
task::{Context, Poll},
11+
};
12+
use tower::Service;
13+
14+
/// A [`MakeService`] that produces AWS Lambda compliant services.
15+
///
16+
/// [`MakeService`]: tower::make::MakeService
17+
#[derive(Debug, Clone)]
18+
pub struct IntoMakeLambdaService<S> {
19+
service: S,
20+
}
21+
22+
impl<S> IntoMakeLambdaService<S> {
23+
pub fn new(service: S) -> Self {
24+
Self { service }
25+
}
26+
}
27+
28+
impl<S> Service<Request> for IntoMakeLambdaService<S>
29+
where
30+
S: Service<Request>,
31+
{
32+
type Error = S::Error;
33+
type Response = S::Response;
34+
type Future = S::Future;
35+
36+
#[inline]
37+
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
38+
self.service.poll_ready(cx).map_err(|err| err.into())
39+
}
40+
41+
fn call(&mut self, event: Request) -> Self::Future {
42+
self.service.call(convert_event(event))
43+
}
44+
}
45+
46+
fn convert_event(request: Request) -> Request {
47+
let raw_path = request.raw_http_path();
48+
let (mut parts, body) = request.into_parts();
49+
let mut path = String::from(parts.uri.path());
50+
51+
if !raw_path.is_empty() && raw_path != path {
52+
path = raw_path;
53+
54+
let uri_parts: uri::Parts = parts.uri.into();
55+
let path_and_query = uri_parts.path_and_query.unwrap();
56+
57+
if let Some(query) = path_and_query.query() {
58+
path.push('?');
59+
path.push_str(query);
60+
}
61+
62+
parts.uri = uri::Uri::builder()
63+
.authority(uri_parts.authority.unwrap())
64+
.scheme(uri_parts.scheme.unwrap())
65+
.path_and_query(path)
66+
.build()
67+
.unwrap();
68+
}
69+
70+
http::Request::from_parts(parts, body)
71+
}

rust-runtime/aws-smithy-http-server/src/routing/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//!
88
//! [Smithy specification]: https://awslabs.github.io/smithy/1.0/spec/core/http-traits.html
99
10+
use self::into_make_lambda_service::IntoMakeLambdaService;
1011
use self::request_spec::RequestSpec;
1112
use self::tiny_map::TinyMap;
1213
use crate::body::{boxed, Body, BoxBody, HttpBody};
@@ -24,6 +25,7 @@ use tower::{Service, ServiceBuilder};
2425
use tower_http::map_response_body::MapResponseBodyLayer;
2526

2627
mod future;
28+
mod into_make_lambda_service;
2729
mod into_make_service;
2830

2931
#[doc(hidden)]
@@ -137,6 +139,18 @@ where
137139
IntoMakeService::new(self)
138140
}
139141

142+
/// Convert this router into a [`MakeService`], that is a [`Service`] whose
143+
/// response is another service.
144+
///
145+
/// This is useful when running your application with AWS Lambda's
146+
/// [`run`].
147+
///
148+
/// [`run`]: lambda_http::run
149+
/// [`MakeService`]: tower::make::MakeService
150+
pub fn into_make_lambda_service(self) -> IntoMakeLambdaService<Self> {
151+
IntoMakeLambdaService::new(self)
152+
}
153+
140154
/// Apply a [`tower::Layer`] to the router.
141155
///
142156
/// All requests to the router will be processed by the layer's

0 commit comments

Comments
 (0)