1#[cfg(test)]
24mod tests;
25
26mod layer;
27mod service;
28
29pub use layer::{Next, TowerLayer};
30pub use service::TowerService;
31
32use std::future::Future;
33use std::io::Read;
34use std::pin::Pin;
35use std::sync::OnceLock;
36use std::task::{Context, Poll};
37
38use bytes::Bytes;
39use http_body::Frame;
40use http_body_util::BodyExt;
41
42use crate::application::{Application, AsyncResponse};
43use crate::core::New;
44use crate::header::Header;
45use crate::range::Range;
46use crate::request::Request;
47use crate::response::{Response, Trailers};
48use crate::server::ConnectionInfo;
49
50pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
52
53const BUFFER_LIMIT: u64 = 1024 * 1024;
56
57const CHUNK: usize = 64 * 1024;
60
61const NOT_COPIED: &[&str] = &["connection", "keep-alive", "transfer-encoding", "upgrade", "proxy-connection", "te", "content-length"];
63
64#[doc(hidden)]
65pub fn runtime() -> &'static tokio::runtime::Runtime {
66 static RUNTIME: OnceLock<tokio::runtime::Runtime> = OnceLock::new();
67 RUNTIME.get_or_init(|| {
68 tokio::runtime::Builder::new_multi_thread()
69 .worker_threads(2)
70 .thread_name("rws-tower")
71 .enable_all()
72 .build()
73 .expect("the tower runtime")
74 })
75}
76
77pub struct Body {
82 inner: Inner,
83}
84
85enum Inner {
86 Full(Option<Bytes>),
87 Channel { rx: tokio::sync::mpsc::Receiver<std::io::Result<Bytes>>, trailers: Option<Trailers> },
88}
89
90impl Body {
91 pub fn empty() -> Body {
93 Body { inner: Inner::Full(None) }
94 }
95
96 pub fn full(bytes: impl Into<Bytes>) -> Body {
98 let bytes = bytes.into();
99 Body { inner: Inner::Full((!bytes.is_empty()).then_some(bytes)) }
100 }
101
102 fn from_reader(mut reader: Box<dyn Read + Send>, trailers: Option<Trailers>) -> Body {
105 let (tx, rx) = tokio::sync::mpsc::channel(4);
106 runtime().spawn_blocking(move || loop {
107 let mut buf = vec![0u8; CHUNK];
108 match reader.read(&mut buf) {
109 Ok(0) => return,
110 Ok(n) => {
111 buf.truncate(n);
112 if tx.blocking_send(Ok(Bytes::from(buf))).is_err() {
113 return;
114 }
115 }
116 Err(e) => {
117 let _ = tx.blocking_send(Err(e));
118 return;
119 }
120 }
121 });
122 Body { inner: Inner::Channel { rx, trailers } }
123 }
124
125 pub fn from_request_body(body: crate::request::Body) -> Body {
127 if body.is_stream() {
128 Body::from_reader(body.into_reader(), None)
129 } else {
130 Body::full(body.to_vec())
131 }
132 }
133}
134
135impl Default for Body {
136 fn default() -> Body {
137 Body::empty()
138 }
139}
140
141impl http_body::Body for Body {
142 type Data = Bytes;
143 type Error = BoxError;
144
145 fn poll_frame(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Frame<Bytes>, BoxError>>> {
146 match &mut self.get_mut().inner {
147 Inner::Full(bytes) => Poll::Ready(bytes.take().map(|b| Ok(Frame::data(b)))),
148 Inner::Channel { rx, trailers } => match rx.poll_recv(cx) {
149 Poll::Ready(Some(Ok(chunk))) => Poll::Ready(Some(Ok(Frame::data(chunk)))),
150 Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(Box::new(e)))),
151 Poll::Ready(None) => {
152 let fields = trailers.take().map(|t| t.get()).unwrap_or_default();
153 if fields.is_empty() {
154 return Poll::Ready(None);
155 }
156 let mut map = http::HeaderMap::new();
157 for h in fields {
158 if let (Ok(name), Ok(value)) = (http::HeaderName::from_bytes(h.name.as_bytes()), http::HeaderValue::from_bytes(h.value.as_bytes())) {
159 map.append(name, value);
160 }
161 }
162 Poll::Ready(Some(Ok(Frame::trailers(map))))
163 }
164 Poll::Pending => Poll::Pending,
165 },
166 }
167 }
168
169 fn is_end_stream(&self) -> bool {
170 matches!(self.inner, Inner::Full(None))
171 }
172
173 fn size_hint(&self) -> http_body::SizeHint {
174 match &self.inner {
175 Inner::Full(bytes) => http_body::SizeHint::with_exact(bytes.as_ref().map_or(0, |b| b.len() as u64)),
176 Inner::Channel { .. } => http_body::SizeHint::default(),
177 }
178 }
179}
180
181fn version_to_http(version: &str) -> http::Version {
184 match version {
185 "HTTP/1.0" => http::Version::HTTP_10,
186 "HTTP/2.0" | "HTTP/2" => http::Version::HTTP_2,
187 "HTTP/3.0" | "HTTP/3" => http::Version::HTTP_3,
188 "HTTP/0.9" => http::Version::HTTP_09,
189 _ => http::Version::HTTP_11,
190 }
191}
192
193fn version_from_http(version: http::Version) -> &'static str {
194 let v = &crate::http::VERSION;
195 match version {
196 http::Version::HTTP_10 => v.http_1_0,
197 http::Version::HTTP_2 => v.http_2_0,
198 http::Version::HTTP_3 => v.http_3_0,
199 _ => v.http_1_1,
200 }
201}
202
203fn header_map(headers: &[Header]) -> http::HeaderMap {
204 let mut map = http::HeaderMap::with_capacity(headers.len());
205 for h in headers {
206 if let (Ok(name), Ok(value)) = (http::HeaderName::from_bytes(h.name.as_bytes()), http::HeaderValue::from_bytes(h.value.as_bytes())) {
208 map.append(name, value);
209 }
210 }
211 map
212}
213
214fn headers_from(map: &http::HeaderMap) -> Vec<Header> {
215 map.iter()
216 .filter_map(|(name, value)| {
217 let value = String::from_utf8_lossy(value.as_bytes()).into_owned();
218 Some(Header::new(name.as_str().to_string(), value))
219 })
220 .collect()
221}
222
223pub fn to_http_request(request: Request) -> http::Request<Body> {
225 let mut builder = http::Request::builder()
226 .method(http::Method::from_bytes(request.method.as_bytes()).unwrap_or(http::Method::GET))
227 .uri(http::Uri::try_from(request.request_uri.as_str()).unwrap_or_else(|_| http::Uri::from_static("/")))
228 .version(version_to_http(&request.http_version));
229 if let Some(headers) = builder.headers_mut() {
230 *headers = header_map(&request.headers);
231 }
232 builder.body(Body::from_request_body(request.body)).expect("method, URI and version are valid")
233}
234
235pub async fn from_http_request<B>(request: http::Request<B>) -> Result<Request, BoxError>
237where
238 B: http_body::Body<Data = Bytes>,
239 B::Error: Into<BoxError>,
240{
241 let (parts, body) = request.into_parts();
242 let bytes = body.collect().await.map_err(Into::into)?.to_bytes();
243 Ok(Request {
244 method: parts.method.as_str().to_string(),
245 request_uri: parts.uri.path_and_query().map(|p| p.as_str().to_string()).unwrap_or_else(|| "/".to_string()),
246 http_version: version_from_http(parts.version).to_string(),
247 headers: headers_from(&parts.headers),
248 body: bytes.to_vec().into(),
249 })
250}
251
252pub fn to_http_response(mut response: Response) -> http::Response<Body> {
256 let mut headers = header_map(&response.headers);
257 let body = if response.stream_pipe.is_some() || response.stream_file.is_some() {
258 let _enter = runtime().enter();
259 match crate::server::body_stream::spawn_producer(&mut response) {
260 Some(mut chunks) => {
261 let (tx, rx) = tokio::sync::mpsc::channel(4);
262 runtime().spawn(async move {
263 while let Some(chunk) = chunks.recv().await {
264 let chunk = chunk.map(Bytes::from).map_err(std::io::Error::other);
265 let failed = chunk.is_err();
266 if tx.send(chunk).await.is_err() || failed {
267 return;
268 }
269 }
270 });
271 Body { inner: Inner::Channel { rx, trailers: response.trailers.take() } }
272 }
273 None => Body::empty(),
274 }
275 } else {
276 let ranges = std::mem::take(&mut response.content_range_list);
277 let (content_type, bytes) = match ranges.len() {
278 0 => (None, Vec::new()),
279 1 => {
280 if let Some(value) = crate::response::content_range_header_value(response.status_code, &ranges[0]) {
281 if let Ok(value) = http::HeaderValue::from_str(&value) {
282 headers.insert(http::header::CONTENT_RANGE, value);
283 }
284 }
285 let range = ranges.into_iter().next().expect("one range");
286 (Some(range.content_type), range.body)
287 }
288 _ => (Some(Range::multipart_content_type(&ranges)), Response::generate_body(ranges)),
289 };
290 if let Some(content_type) = content_type.and_then(|t| http::HeaderValue::from_str(&t).ok()) {
291 headers.insert(http::header::CONTENT_TYPE, content_type);
292 }
293 match response.trailers.take() {
294 Some(trailers) if !trailers.get().is_empty() => {
296 let (tx, rx) = tokio::sync::mpsc::channel(1);
297 let _ = tx.try_send(Ok(Bytes::from(bytes)));
298 Body { inner: Inner::Channel { rx, trailers: Some(trailers) } }
299 }
300 _ => Body::full(bytes),
301 }
302 };
303 let mut out = http::Response::new(body);
304 *out.status_mut() = http::StatusCode::from_u16(response.status_code as u16).unwrap_or(http::StatusCode::INTERNAL_SERVER_ERROR);
305 *out.headers_mut() = headers;
306 out
307}
308
309pub async fn from_http_response<B>(response: http::Response<B>) -> Result<Response, BoxError>
313where
314 B: http_body::Body<Data = Bytes> + Send + 'static,
315 B::Error: Into<BoxError>,
316{
317 let (parts, body) = response.into_parts();
318 let mut response = Response::new();
319 response.status_code = parts.status.as_u16() as i16;
320 response.reason_phrase = parts.status.canonical_reason().unwrap_or("").to_string();
321 let content_type = parts.headers.get(http::header::CONTENT_TYPE).and_then(|v| v.to_str().ok()).map(str::to_string);
322 let grpc = content_type.as_deref().is_some_and(|t| t.starts_with("application/grpc"));
323 response.headers = headers_from(&parts.headers)
324 .into_iter()
325 .filter(|h| !NOT_COPIED.iter().any(|n| h.name.eq_ignore_ascii_case(n)) && !h.name.eq_ignore_ascii_case("content-type"))
326 .collect();
327 let content_type = content_type.unwrap_or_else(|| "application/octet-stream".to_string());
328
329 if body.is_end_stream() {
331 if grpc {
332 response.headers.push(Header::new("content-type".to_string(), content_type));
333 }
334 return Ok(response);
335 }
336 let exact = body.size_hint().exact();
337 if !grpc && exact.is_some_and(|n| n <= BUFFER_LIMIT) {
338 let collected = body.collect().await.map_err(Into::into)?;
339 if let Some(trailers) = collected.trailers() {
340 response.trailers = Some(Trailers::with(headers_from(trailers)));
341 }
342 let bytes = collected.to_bytes();
343 if !bytes.is_empty() {
344 response.content_range_list = vec![Range::get_content_range(bytes.to_vec(), content_type)];
345 }
346 return Ok(response);
347 }
348
349 response.headers.push(Header::new("content-type".to_string(), content_type));
352 let trailers = Trailers::new();
353 response.trailers = Some(trailers.clone());
354 let (tx, rx) = tokio::sync::mpsc::channel(4);
355 response.stream_pipe = Some(Box::new(crate::server::body_stream::ChannelReader::new(rx)));
356 runtime().spawn(async move {
357 let mut body = std::pin::pin!(body);
358 loop {
359 let next: Option<Result<Frame<Bytes>, BoxError>> = body.frame().await.map(|r| r.map_err(Into::into));
361 match next {
362 Some(Ok(frame)) => {
363 let frame = match frame.into_data() {
364 Ok(data) => {
365 if tx.send(Ok(data.to_vec())).await.is_err() {
366 return; }
368 continue;
369 }
370 Err(frame) => frame,
371 };
372 if let Ok(fields) = frame.into_trailers() {
373 trailers.set(headers_from(&fields));
375 }
376 }
377 Some(Err(e)) => {
378 let _ = tx.send(Err(std::io::Error::other(e))).await;
379 return;
380 }
381 None => return,
382 }
383 }
384 });
385 Ok(response)
386}
387
388async fn call<S, Req>(mut service: S, request: Req) -> Result<S::Response, BoxError>
390where
391 S: tower_service::Service<Req>,
392 S::Error: Into<BoxError>,
393{
394 std::future::poll_fn(|cx| service.poll_ready(cx)).await.map_err(Into::into)?;
395 service.call(request).await.map_err(Into::into)
396}
397
398#[derive(Clone)]
414pub struct TowerApp<S> {
415 service: S,
416}
417
418impl<S> TowerApp<S> {
419 pub fn new(service: S) -> TowerApp<S> {
420 TowerApp { service }
421 }
422}
423
424pub fn mount<S, A>(prefix: &str, service: S, fallback: A) -> Mount<S, A> {
427 Mount { prefix: prefix.to_string(), service: TowerApp::new(service), fallback }
428}
429
430#[derive(Clone)]
432pub struct Mount<S, A> {
433 prefix: String,
434 service: TowerApp<S>,
435 fallback: A,
436}
437
438impl<S, A> Mount<S, A> {
439 fn routed(&self, request: &Request) -> bool {
440 crate::url::URL::request_target_path(&request.request_uri).unwrap_or("").starts_with(&self.prefix)
441 }
442}
443
444impl<S, B> TowerApp<S>
445where
446 S: tower_service::Service<http::Request<Body>, Response = http::Response<B>> + Clone + Send + Sync + 'static,
447 S::Future: Send + 'static,
448 S::Error: Into<BoxError>,
449 B: http_body::Body<Data = Bytes> + Send + 'static,
450 B::Error: Into<BoxError>,
451{
452 fn respond(&self, request: Request) -> impl Future<Output = Result<Response, String>> + Send + 'static {
453 let service = self.service.clone();
454 async move {
455 let response = call(service, to_http_request(request)).await.map_err(|e| format!("tower service: {e}"))?;
456 from_http_response(response).await.map_err(|e| format!("tower service body: {e}"))
457 }
458 }
459}
460
461impl<S, B> Application for TowerApp<S>
462where
463 S: tower_service::Service<http::Request<Body>, Response = http::Response<B>> + Clone + Send + Sync + 'static,
464 S::Future: Send + 'static,
465 S::Error: Into<BoxError>,
466 B: http_body::Body<Data = Bytes> + Send + 'static,
467 B::Error: Into<BoxError>,
468{
469 fn execute(&self, request: &Request, _connection: &ConnectionInfo) -> Result<Response, String> {
470 let (tx, rx) = std::sync::mpsc::sync_channel(1);
471 let work = self.respond(request.clone());
472 runtime().spawn(async move {
473 let _ = tx.send(work.await);
474 });
475 rx.recv().map_err(|_| "tower service: dropped".to_string())?
476 }
477
478 fn execute_async<'a>(&'a self, request: &'a Request, _connection: &'a ConnectionInfo) -> Option<AsyncResponse<'a>> {
479 let work = runtime().spawn(self.respond(request.clone()));
480 Some(Box::pin(async move { work.await.map_err(|e| format!("tower service: {e}"))? }))
481 }
482
483 fn streams_body(&self, _request: &Request, _connection: &ConnectionInfo) -> bool {
484 true
485 }
486}
487
488impl<S, B, A> Application for Mount<S, A>
489where
490 S: tower_service::Service<http::Request<Body>, Response = http::Response<B>> + Clone + Send + Sync + 'static,
491 S::Future: Send + 'static,
492 S::Error: Into<BoxError>,
493 B: http_body::Body<Data = Bytes> + Send + 'static,
494 B::Error: Into<BoxError>,
495 A: Application,
496{
497 fn execute(&self, request: &Request, connection: &ConnectionInfo) -> Result<Response, String> {
498 if self.routed(request) {
499 self.service.execute(request, connection)
500 } else {
501 self.fallback.execute(request, connection)
502 }
503 }
504
505 fn runs_inline(&self, request: &Request, connection: &ConnectionInfo) -> bool {
506 !self.routed(request) && self.fallback.runs_inline(request, connection)
507 }
508
509 fn execute_async<'a>(&'a self, request: &'a Request, connection: &'a ConnectionInfo) -> Option<AsyncResponse<'a>> {
510 if self.routed(request) {
511 self.service.execute_async(request, connection)
512 } else {
513 self.fallback.execute_async(request, connection)
514 }
515 }
516
517 fn streams_body(&self, request: &Request, connection: &ConnectionInfo) -> bool {
518 self.routed(request) || self.fallback.streams_body(request, connection)
519 }
520}
521
522#[doc(hidden)]
528pub fn block_on<F: Future>(future: F) -> F::Output {
529 struct Unpark(std::thread::Thread);
530 impl std::task::Wake for Unpark {
531 fn wake(self: std::sync::Arc<Self>) {
532 self.0.unpark();
533 }
534 fn wake_by_ref(self: &std::sync::Arc<Self>) {
535 self.0.unpark();
536 }
537 }
538 let _enter = runtime().enter();
539 let waker = std::task::Waker::from(std::sync::Arc::new(Unpark(std::thread::current())));
540 let mut cx = Context::from_waker(&waker);
541 let mut future = std::pin::pin!(future);
542 loop {
543 match future.as_mut().poll(&mut cx) {
544 Poll::Ready(output) => return output,
545 Poll::Pending => std::thread::park(),
546 }
547 }
548}