1 use super::{IntoResponseParts, Response, ResponseParts}; 2 use crate::{body, BoxError}; 3 use bytes::{buf::Chain, Buf, Bytes, BytesMut}; 4 use http::{ 5 header::{self, HeaderMap, HeaderName, HeaderValue}, 6 Extensions, StatusCode, 7 }; 8 use http_body::{ 9 combinators::{MapData, MapErr}, 10 Empty, Full, SizeHint, 11 }; 12 use std::{ 13 borrow::Cow, 14 convert::Infallible, 15 fmt, 16 pin::Pin, 17 task::{Context, Poll}, 18 }; 19 20 /// Trait for generating responses. 21 /// 22 /// Types that implement `IntoResponse` can be returned from handlers. 23 /// 24 /// # Implementing `IntoResponse` 25 /// 26 /// You generally shouldn't have to implement `IntoResponse` manually, as axum 27 /// provides implementations for many common types. 28 /// 29 /// However it might be necessary if you have a custom error type that you want 30 /// to return from handlers: 31 /// 32 /// ```rust 33 /// use axum::{ 34 /// Router, 35 /// body::{self, Bytes}, 36 /// routing::get, 37 /// http::StatusCode, 38 /// response::{IntoResponse, Response}, 39 /// }; 40 /// 41 /// enum MyError { 42 /// SomethingWentWrong, 43 /// SomethingElseWentWrong, 44 /// } 45 /// 46 /// impl IntoResponse for MyError { 47 /// fn into_response(self) -> Response { 48 /// let body = match self { 49 /// MyError::SomethingWentWrong => "something went wrong", 50 /// MyError::SomethingElseWentWrong => "something else went wrong", 51 /// }; 52 /// 53 /// // its often easiest to implement `IntoResponse` by calling other implementations 54 /// (StatusCode::INTERNAL_SERVER_ERROR, body).into_response() 55 /// } 56 /// } 57 /// 58 /// // `Result<impl IntoResponse, MyError>` can now be returned from handlers 59 /// let app = Router::new().route("/", get(handler)); 60 /// 61 /// async fn handler() -> Result<(), MyError> { 62 /// Err(MyError::SomethingWentWrong) 63 /// } 64 /// # async { 65 /// # hyper::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); 66 /// # }; 67 /// ``` 68 /// 69 /// Or if you have a custom body type you'll also need to implement 70 /// `IntoResponse` for it: 71 /// 72 /// ```rust 73 /// use axum::{ 74 /// body, 75 /// routing::get, 76 /// response::{IntoResponse, Response}, 77 /// Router, 78 /// }; 79 /// use http_body::Body; 80 /// use http::HeaderMap; 81 /// use bytes::Bytes; 82 /// use std::{ 83 /// convert::Infallible, 84 /// task::{Poll, Context}, 85 /// pin::Pin, 86 /// }; 87 /// 88 /// struct MyBody; 89 /// 90 /// // First implement `Body` for `MyBody`. This could for example use 91 /// // some custom streaming protocol. 92 /// impl Body for MyBody { 93 /// type Data = Bytes; 94 /// type Error = Infallible; 95 /// 96 /// fn poll_data( 97 /// self: Pin<&mut Self>, 98 /// cx: &mut Context<'_> 99 /// ) -> Poll<Option<Result<Self::Data, Self::Error>>> { 100 /// # unimplemented!() 101 /// // ... 102 /// } 103 /// 104 /// fn poll_trailers( 105 /// self: Pin<&mut Self>, 106 /// cx: &mut Context<'_> 107 /// ) -> Poll<Result<Option<HeaderMap>, Self::Error>> { 108 /// # unimplemented!() 109 /// // ... 110 /// } 111 /// } 112 /// 113 /// // Now we can implement `IntoResponse` directly for `MyBody` 114 /// impl IntoResponse for MyBody { 115 /// fn into_response(self) -> Response { 116 /// Response::new(body::boxed(self)) 117 /// } 118 /// } 119 /// 120 /// // `MyBody` can now be returned from handlers. 121 /// let app = Router::new().route("/", get(|| async { MyBody })); 122 /// # async { 123 /// # hyper::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap(); 124 /// # }; 125 /// ``` 126 pub trait IntoResponse { 127 /// Create a response. into_response(self) -> Response128 fn into_response(self) -> Response; 129 } 130 131 impl IntoResponse for StatusCode { into_response(self) -> Response132 fn into_response(self) -> Response { 133 let mut res = ().into_response(); 134 *res.status_mut() = self; 135 res 136 } 137 } 138 139 impl IntoResponse for () { into_response(self) -> Response140 fn into_response(self) -> Response { 141 Empty::new().into_response() 142 } 143 } 144 145 impl IntoResponse for Infallible { into_response(self) -> Response146 fn into_response(self) -> Response { 147 match self {} 148 } 149 } 150 151 impl<T, E> IntoResponse for Result<T, E> 152 where 153 T: IntoResponse, 154 E: IntoResponse, 155 { into_response(self) -> Response156 fn into_response(self) -> Response { 157 match self { 158 Ok(value) => value.into_response(), 159 Err(err) => err.into_response(), 160 } 161 } 162 } 163 164 impl<B> IntoResponse for Response<B> 165 where 166 B: http_body::Body<Data = Bytes> + Send + 'static, 167 B::Error: Into<BoxError>, 168 { into_response(self) -> Response169 fn into_response(self) -> Response { 170 self.map(body::boxed) 171 } 172 } 173 174 impl IntoResponse for http::response::Parts { into_response(self) -> Response175 fn into_response(self) -> Response { 176 Response::from_parts(self, body::boxed(Empty::new())) 177 } 178 } 179 180 impl IntoResponse for Full<Bytes> { into_response(self) -> Response181 fn into_response(self) -> Response { 182 Response::new(body::boxed(self)) 183 } 184 } 185 186 impl IntoResponse for Empty<Bytes> { into_response(self) -> Response187 fn into_response(self) -> Response { 188 Response::new(body::boxed(self)) 189 } 190 } 191 192 impl<E> IntoResponse for http_body::combinators::BoxBody<Bytes, E> 193 where 194 E: Into<BoxError> + 'static, 195 { into_response(self) -> Response196 fn into_response(self) -> Response { 197 Response::new(body::boxed(self)) 198 } 199 } 200 201 impl<E> IntoResponse for http_body::combinators::UnsyncBoxBody<Bytes, E> 202 where 203 E: Into<BoxError> + 'static, 204 { into_response(self) -> Response205 fn into_response(self) -> Response { 206 Response::new(body::boxed(self)) 207 } 208 } 209 210 impl<B, F> IntoResponse for MapData<B, F> 211 where 212 B: http_body::Body + Send + 'static, 213 F: FnMut(B::Data) -> Bytes + Send + 'static, 214 B::Error: Into<BoxError>, 215 { into_response(self) -> Response216 fn into_response(self) -> Response { 217 Response::new(body::boxed(self)) 218 } 219 } 220 221 impl<B, F, E> IntoResponse for MapErr<B, F> 222 where 223 B: http_body::Body<Data = Bytes> + Send + 'static, 224 F: FnMut(B::Error) -> E + Send + 'static, 225 E: Into<BoxError>, 226 { into_response(self) -> Response227 fn into_response(self) -> Response { 228 Response::new(body::boxed(self)) 229 } 230 } 231 232 impl IntoResponse for &'static str { into_response(self) -> Response233 fn into_response(self) -> Response { 234 Cow::Borrowed(self).into_response() 235 } 236 } 237 238 impl IntoResponse for String { into_response(self) -> Response239 fn into_response(self) -> Response { 240 Cow::<'static, str>::Owned(self).into_response() 241 } 242 } 243 244 impl IntoResponse for Cow<'static, str> { into_response(self) -> Response245 fn into_response(self) -> Response { 246 let mut res = Full::from(self).into_response(); 247 res.headers_mut().insert( 248 header::CONTENT_TYPE, 249 HeaderValue::from_static(mime::TEXT_PLAIN_UTF_8.as_ref()), 250 ); 251 res 252 } 253 } 254 255 impl IntoResponse for Bytes { into_response(self) -> Response256 fn into_response(self) -> Response { 257 let mut res = Full::from(self).into_response(); 258 res.headers_mut().insert( 259 header::CONTENT_TYPE, 260 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()), 261 ); 262 res 263 } 264 } 265 266 impl IntoResponse for BytesMut { into_response(self) -> Response267 fn into_response(self) -> Response { 268 self.freeze().into_response() 269 } 270 } 271 272 impl<T, U> IntoResponse for Chain<T, U> 273 where 274 T: Buf + Unpin + Send + 'static, 275 U: Buf + Unpin + Send + 'static, 276 { into_response(self) -> Response277 fn into_response(self) -> Response { 278 let (first, second) = self.into_inner(); 279 let mut res = Response::new(body::boxed(BytesChainBody { 280 first: Some(first), 281 second: Some(second), 282 })); 283 res.headers_mut().insert( 284 header::CONTENT_TYPE, 285 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()), 286 ); 287 res 288 } 289 } 290 291 struct BytesChainBody<T, U> { 292 first: Option<T>, 293 second: Option<U>, 294 } 295 296 impl<T, U> http_body::Body for BytesChainBody<T, U> 297 where 298 T: Buf + Unpin, 299 U: Buf + Unpin, 300 { 301 type Data = Bytes; 302 type Error = Infallible; 303 poll_data( mut self: Pin<&mut Self>, _cx: &mut Context<'_>, ) -> Poll<Option<Result<Self::Data, Self::Error>>>304 fn poll_data( 305 mut self: Pin<&mut Self>, 306 _cx: &mut Context<'_>, 307 ) -> Poll<Option<Result<Self::Data, Self::Error>>> { 308 if let Some(mut buf) = self.first.take() { 309 let bytes = buf.copy_to_bytes(buf.remaining()); 310 return Poll::Ready(Some(Ok(bytes))); 311 } 312 313 if let Some(mut buf) = self.second.take() { 314 let bytes = buf.copy_to_bytes(buf.remaining()); 315 return Poll::Ready(Some(Ok(bytes))); 316 } 317 318 Poll::Ready(None) 319 } 320 poll_trailers( self: Pin<&mut Self>, _cx: &mut Context<'_>, ) -> Poll<Result<Option<HeaderMap>, Self::Error>>321 fn poll_trailers( 322 self: Pin<&mut Self>, 323 _cx: &mut Context<'_>, 324 ) -> Poll<Result<Option<HeaderMap>, Self::Error>> { 325 Poll::Ready(Ok(None)) 326 } 327 is_end_stream(&self) -> bool328 fn is_end_stream(&self) -> bool { 329 self.first.is_none() && self.second.is_none() 330 } 331 size_hint(&self) -> SizeHint332 fn size_hint(&self) -> SizeHint { 333 match (self.first.as_ref(), self.second.as_ref()) { 334 (Some(first), Some(second)) => { 335 let total_size = first.remaining() + second.remaining(); 336 SizeHint::with_exact(total_size as u64) 337 } 338 (Some(buf), None) => SizeHint::with_exact(buf.remaining() as u64), 339 (None, Some(buf)) => SizeHint::with_exact(buf.remaining() as u64), 340 (None, None) => SizeHint::with_exact(0), 341 } 342 } 343 } 344 345 impl IntoResponse for &'static [u8] { into_response(self) -> Response346 fn into_response(self) -> Response { 347 Cow::Borrowed(self).into_response() 348 } 349 } 350 351 impl<const N: usize> IntoResponse for &'static [u8; N] { into_response(self) -> Response352 fn into_response(self) -> Response { 353 self.as_slice().into_response() 354 } 355 } 356 357 impl<const N: usize> IntoResponse for [u8; N] { into_response(self) -> Response358 fn into_response(self) -> Response { 359 self.to_vec().into_response() 360 } 361 } 362 363 impl IntoResponse for Vec<u8> { into_response(self) -> Response364 fn into_response(self) -> Response { 365 Cow::<'static, [u8]>::Owned(self).into_response() 366 } 367 } 368 369 impl IntoResponse for Cow<'static, [u8]> { into_response(self) -> Response370 fn into_response(self) -> Response { 371 let mut res = Full::from(self).into_response(); 372 res.headers_mut().insert( 373 header::CONTENT_TYPE, 374 HeaderValue::from_static(mime::APPLICATION_OCTET_STREAM.as_ref()), 375 ); 376 res 377 } 378 } 379 380 impl<R> IntoResponse for (StatusCode, R) 381 where 382 R: IntoResponse, 383 { into_response(self) -> Response384 fn into_response(self) -> Response { 385 let mut res = self.1.into_response(); 386 *res.status_mut() = self.0; 387 res 388 } 389 } 390 391 impl IntoResponse for HeaderMap { into_response(self) -> Response392 fn into_response(self) -> Response { 393 let mut res = ().into_response(); 394 *res.headers_mut() = self; 395 res 396 } 397 } 398 399 impl IntoResponse for Extensions { into_response(self) -> Response400 fn into_response(self) -> Response { 401 let mut res = ().into_response(); 402 *res.extensions_mut() = self; 403 res 404 } 405 } 406 407 impl<K, V, const N: usize> IntoResponse for [(K, V); N] 408 where 409 K: TryInto<HeaderName>, 410 K::Error: fmt::Display, 411 V: TryInto<HeaderValue>, 412 V::Error: fmt::Display, 413 { into_response(self) -> Response414 fn into_response(self) -> Response { 415 (self, ()).into_response() 416 } 417 } 418 419 impl<R> IntoResponse for (http::response::Parts, R) 420 where 421 R: IntoResponse, 422 { into_response(self) -> Response423 fn into_response(self) -> Response { 424 let (parts, res) = self; 425 (parts.status, parts.headers, parts.extensions, res).into_response() 426 } 427 } 428 429 impl<R> IntoResponse for (http::response::Response<()>, R) 430 where 431 R: IntoResponse, 432 { into_response(self) -> Response433 fn into_response(self) -> Response { 434 let (template, res) = self; 435 let (parts, ()) = template.into_parts(); 436 (parts, res).into_response() 437 } 438 } 439 440 macro_rules! impl_into_response { 441 ( $($ty:ident),* $(,)? ) => { 442 #[allow(non_snake_case)] 443 impl<R, $($ty,)*> IntoResponse for ($($ty),*, R) 444 where 445 $( $ty: IntoResponseParts, )* 446 R: IntoResponse, 447 { 448 fn into_response(self) -> Response { 449 let ($($ty),*, res) = self; 450 451 let res = res.into_response(); 452 let parts = ResponseParts { res }; 453 454 $( 455 let parts = match $ty.into_response_parts(parts) { 456 Ok(parts) => parts, 457 Err(err) => { 458 return err.into_response(); 459 } 460 }; 461 )* 462 463 parts.res 464 } 465 } 466 467 #[allow(non_snake_case)] 468 impl<R, $($ty,)*> IntoResponse for (StatusCode, $($ty),*, R) 469 where 470 $( $ty: IntoResponseParts, )* 471 R: IntoResponse, 472 { 473 fn into_response(self) -> Response { 474 let (status, $($ty),*, res) = self; 475 476 let res = res.into_response(); 477 let parts = ResponseParts { res }; 478 479 $( 480 let parts = match $ty.into_response_parts(parts) { 481 Ok(parts) => parts, 482 Err(err) => { 483 return err.into_response(); 484 } 485 }; 486 )* 487 488 (status, parts.res).into_response() 489 } 490 } 491 492 #[allow(non_snake_case)] 493 impl<R, $($ty,)*> IntoResponse for (http::response::Parts, $($ty),*, R) 494 where 495 $( $ty: IntoResponseParts, )* 496 R: IntoResponse, 497 { 498 fn into_response(self) -> Response { 499 let (outer_parts, $($ty),*, res) = self; 500 501 let res = res.into_response(); 502 let parts = ResponseParts { res }; 503 $( 504 let parts = match $ty.into_response_parts(parts) { 505 Ok(parts) => parts, 506 Err(err) => { 507 return err.into_response(); 508 } 509 }; 510 )* 511 512 (outer_parts, parts.res).into_response() 513 } 514 } 515 516 #[allow(non_snake_case)] 517 impl<R, $($ty,)*> IntoResponse for (http::response::Response<()>, $($ty),*, R) 518 where 519 $( $ty: IntoResponseParts, )* 520 R: IntoResponse, 521 { 522 fn into_response(self) -> Response { 523 let (template, $($ty),*, res) = self; 524 let (parts, ()) = template.into_parts(); 525 (parts, $($ty),*, res).into_response() 526 } 527 } 528 } 529 } 530 531 all_the_tuples_no_last_special_case!(impl_into_response); 532