1 use super::{IntoResponse, IntoResponseParts, Response, ResponseParts, TryIntoHeaderError}; 2 use http::header::{HeaderName, HeaderValue}; 3 use std::fmt; 4 5 /// Append headers to a response. 6 /// 7 /// Returning something like `[("content-type", "foo=bar")]` from a handler will override any 8 /// existing `content-type` headers. If instead you want to append headers, use `AppendHeaders`: 9 /// 10 /// ```rust 11 /// use axum::{ 12 /// response::{AppendHeaders, IntoResponse}, 13 /// http::header::SET_COOKIE, 14 /// }; 15 /// 16 /// async fn handler() -> impl IntoResponse { 17 /// // something that sets the `set-cookie` header 18 /// let set_some_cookies = /* ... */ 19 /// # axum::http::HeaderMap::new(); 20 /// 21 /// ( 22 /// set_some_cookies, 23 /// // append two `set-cookie` headers to the response 24 /// // without overriding the ones added by `set_some_cookies` 25 /// AppendHeaders([ 26 /// (SET_COOKIE, "foo=bar"), 27 /// (SET_COOKIE, "baz=qux"), 28 /// ]) 29 /// ) 30 /// } 31 /// ``` 32 #[derive(Debug)] 33 #[must_use] 34 pub struct AppendHeaders<I>(pub I); 35 36 impl<I, K, V> IntoResponse for AppendHeaders<I> 37 where 38 I: IntoIterator<Item = (K, V)>, 39 K: TryInto<HeaderName>, 40 K::Error: fmt::Display, 41 V: TryInto<HeaderValue>, 42 V::Error: fmt::Display, 43 { into_response(self) -> Response44 fn into_response(self) -> Response { 45 (self, ()).into_response() 46 } 47 } 48 49 impl<I, K, V> IntoResponseParts for AppendHeaders<I> 50 where 51 I: IntoIterator<Item = (K, V)>, 52 K: TryInto<HeaderName>, 53 K::Error: fmt::Display, 54 V: TryInto<HeaderValue>, 55 V::Error: fmt::Display, 56 { 57 type Error = TryIntoHeaderError<K::Error, V::Error>; 58 into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error>59 fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> { 60 for (key, value) in self.0 { 61 let key = key.try_into().map_err(TryIntoHeaderError::key)?; 62 let value = value.try_into().map_err(TryIntoHeaderError::value)?; 63 res.headers_mut().append(key, value); 64 } 65 66 Ok(res) 67 } 68 } 69