aws_lambda_runtime_proxy/
server.rs1use crate::LambdaRuntimeApiClient;
2use anyhow::Result;
3use hyper::{
4 body::{Body, Incoming},
5 server::conn::http1,
6 service::service_fn,
7 Request, Response,
8};
9use hyper_util::rt::TokioIo;
10use std::{future::Future, net::SocketAddr};
11use tokio::{io, net::TcpListener};
12use tracing::{debug, error};
13
14pub struct MockLambdaRuntimeApiServer(TcpListener);
30
31impl MockLambdaRuntimeApiServer {
32 pub async fn bind(port: u16) -> io::Result<Self> {
34 let listener = TcpListener::bind(SocketAddr::from(([127, 0, 0, 1], port))).await?;
35 debug!("Listening on: {}", listener.local_addr()?);
36 Ok(Self(listener))
37 }
38
39 pub async fn handle_next<ResBody, Fut>(
41 &self,
42 processor: impl Fn(Request<Incoming>) -> Fut + Send + Sync + 'static,
43 ) -> io::Result<()>
44 where
45 ResBody: hyper::body::Body + Send + 'static,
46 <ResBody as Body>::Error: Into<Box<dyn std::error::Error + Send + Sync>> + Send,
47 Fut: Future<Output = Result<Response<ResBody>>> + Send,
48 <ResBody as Body>::Data: Send,
49 {
50 let (stream, peer) = self.0.accept().await?;
51 debug!("Accepted connection from: {}", peer);
52
53 tokio::spawn(async move {
56 if let Err(err) = http1::Builder::new()
57 .serve_connection(
58 TokioIo::new(stream),
59 service_fn(|req| async { processor(req).await }),
60 )
61 .await
62 {
63 error!("Error serving connection: {:?}", err);
64 }
65 });
66
67 Ok(())
68 }
69
70 pub async fn serve<ResBody, Fut>(
72 &self,
73 processor: impl Fn(Request<Incoming>) -> Fut + Send + Sync + Clone + 'static,
74 ) where
75 Fut: Future<Output = Result<Response<ResBody>>> + Send,
76 ResBody: hyper::body::Body + Send + 'static,
77 <ResBody as Body>::Error: Into<Box<dyn std::error::Error + Send + Sync>> + Send,
78 <ResBody as Body>::Data: Send,
79 {
80 loop {
81 if let Err(err) = self.handle_next(processor.clone()).await {
82 error!("Error handling connection: {:?}", err);
83 }
84 }
85 }
86
87 pub async fn passthrough(&self) {
90 self
91 .serve(|req| async {
92 LambdaRuntimeApiClient::new().await?.forward(req).await
96 })
97 .await
98 }
99}