mirror of
https://github.com/tokio-rs/axum.git
synced 2024-10-24 01:46:51 +02:00
parent
83e1a15040
commit
afcefb4a70
7 changed files with 78 additions and 25 deletions
|
@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
- None.
|
- **added:** Add `AppendHeaders` for appending headers to a response rather than overriding them ([#927])
|
||||||
|
|
||||||
|
[#927]: https://github.com/tokio-rs/axum/pull/927
|
||||||
|
|
||||||
# 0.2.1 (03. April, 2022)
|
# 0.2.1 (03. April, 2022)
|
||||||
|
|
||||||
|
|
65
axum-core/src/response/append_headers.rs
Normal file
65
axum-core/src/response/append_headers.rs
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
use super::{IntoResponse, IntoResponseParts, Response, ResponseParts, TryIntoHeaderError};
|
||||||
|
use http::header::{HeaderName, HeaderValue};
|
||||||
|
use std::{convert::TryInto, fmt};
|
||||||
|
|
||||||
|
/// Append headers to a response.
|
||||||
|
///
|
||||||
|
/// Returning something like `[("content-type", "foo=bar")]` from a handler will override any
|
||||||
|
/// existing `content-type` headers. If instead you want to append headers, use `AppendHeaders`:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use axum::{
|
||||||
|
/// response::{AppendHeaders, IntoResponse},
|
||||||
|
/// http::header::SET_COOKIE,
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// async fn handler() -> impl IntoResponse {
|
||||||
|
/// // something that sets the `set-cookie` header
|
||||||
|
/// let set_some_cookies = /* ... */
|
||||||
|
/// # axum::http::HeaderMap::new();
|
||||||
|
///
|
||||||
|
/// (
|
||||||
|
/// set_some_cookies,
|
||||||
|
/// // append two `set-cookie` headers to the response
|
||||||
|
/// // without overriding the ones added by `set_some_cookies`
|
||||||
|
/// AppendHeaders([
|
||||||
|
/// (SET_COOKIE, "foo=bar"),
|
||||||
|
/// (SET_COOKIE, "baz=qux"),
|
||||||
|
/// ])
|
||||||
|
/// )
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AppendHeaders<K, V, const N: usize>(pub [(K, V); N]);
|
||||||
|
|
||||||
|
impl<K, V, const N: usize> IntoResponse for AppendHeaders<K, V, N>
|
||||||
|
where
|
||||||
|
K: TryInto<HeaderName>,
|
||||||
|
K::Error: fmt::Display,
|
||||||
|
V: TryInto<HeaderValue>,
|
||||||
|
V::Error: fmt::Display,
|
||||||
|
{
|
||||||
|
fn into_response(self) -> Response {
|
||||||
|
(self, ()).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K, V, const N: usize> IntoResponseParts for AppendHeaders<K, V, N>
|
||||||
|
where
|
||||||
|
K: TryInto<HeaderName>,
|
||||||
|
K::Error: fmt::Display,
|
||||||
|
V: TryInto<HeaderValue>,
|
||||||
|
V::Error: fmt::Display,
|
||||||
|
{
|
||||||
|
type Error = TryIntoHeaderError<K::Error, V::Error>;
|
||||||
|
|
||||||
|
fn into_response_parts(self, mut res: ResponseParts) -> Result<ResponseParts, Self::Error> {
|
||||||
|
for (key, value) in self.0 {
|
||||||
|
let key = key.try_into().map_err(TryIntoHeaderError::key)?;
|
||||||
|
let value = value.try_into().map_err(TryIntoHeaderError::value)?;
|
||||||
|
res.headers_mut().append(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
}
|
|
@ -392,27 +392,7 @@ where
|
||||||
V::Error: fmt::Display,
|
V::Error: fmt::Display,
|
||||||
{
|
{
|
||||||
fn into_response(self) -> Response {
|
fn into_response(self) -> Response {
|
||||||
let mut res = ().into_response();
|
(self, ()).into_response()
|
||||||
|
|
||||||
for (key, value) in self {
|
|
||||||
let key = match key.try_into() {
|
|
||||||
Ok(key) => key,
|
|
||||||
Err(err) => {
|
|
||||||
return (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let value = match value.try_into() {
|
|
||||||
Ok(value) => value,
|
|
||||||
Err(err) => {
|
|
||||||
return (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
res.headers_mut().insert(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,13 +161,13 @@ pub struct TryIntoHeaderError<K, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, V> TryIntoHeaderError<K, V> {
|
impl<K, V> TryIntoHeaderError<K, V> {
|
||||||
fn key(err: K) -> Self {
|
pub(super) fn key(err: K) -> Self {
|
||||||
Self {
|
Self {
|
||||||
kind: TryIntoHeaderErrorKind::Key(err),
|
kind: TryIntoHeaderErrorKind::Key(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn value(err: V) -> Self {
|
pub(super) fn value(err: V) -> Self {
|
||||||
Self {
|
Self {
|
||||||
kind: TryIntoHeaderErrorKind::Value(err),
|
kind: TryIntoHeaderErrorKind::Value(err),
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,12 @@
|
||||||
|
|
||||||
use crate::body::BoxBody;
|
use crate::body::BoxBody;
|
||||||
|
|
||||||
|
mod append_headers;
|
||||||
mod into_response;
|
mod into_response;
|
||||||
mod into_response_parts;
|
mod into_response_parts;
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
|
append_headers::AppendHeaders,
|
||||||
into_response::IntoResponse,
|
into_response::IntoResponse,
|
||||||
into_response_parts::{IntoResponseParts, ResponseParts, TryIntoHeaderError},
|
into_response_parts::{IntoResponseParts, ResponseParts, TryIntoHeaderError},
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,11 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
- **added:** Add `AppendHeaders` for appending headers to a response rather than overriding them ([#927])
|
||||||
- **added:** Add `axum::extract::multipart::Field::chunk` method for streaming a single chunk from
|
- **added:** Add `axum::extract::multipart::Field::chunk` method for streaming a single chunk from
|
||||||
the field ([#901])
|
the field ([#901])
|
||||||
- **fixed:** Fix trailing slash redirection with query parameters ([#936])
|
- **fixed:** Fix trailing slash redirection with query parameters ([#936])
|
||||||
|
|
||||||
[#901]: https://github.com/tokio-rs/axum/pull/901
|
[#901]: https://github.com/tokio-rs/axum/pull/901
|
||||||
|
[#927]: https://github.com/tokio-rs/axum/pull/927
|
||||||
[#936]: https://github.com/tokio-rs/axum/pull/936
|
[#936]: https://github.com/tokio-rs/axum/pull/936
|
||||||
|
|
||||||
# 0.5.1 (03. April, 2022)
|
# 0.5.1 (03. April, 2022)
|
||||||
|
|
|
@ -19,7 +19,9 @@ pub use crate::TypedHeader;
|
||||||
pub use crate::Extension;
|
pub use crate::Extension;
|
||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use axum_core::response::{IntoResponse, IntoResponseParts, Response, ResponseParts};
|
pub use axum_core::response::{
|
||||||
|
AppendHeaders, IntoResponse, IntoResponseParts, Response, ResponseParts,
|
||||||
|
};
|
||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use self::{redirect::Redirect, sse::Sse};
|
pub use self::{redirect::Redirect, sse::Sse};
|
||||||
|
|
Loading…
Reference in a new issue