diff --git a/axum-core/CHANGELOG.md b/axum-core/CHANGELOG.md index d2b090ab..ebeed0b9 100644 --- a/axum-core/CHANGELOG.md +++ b/axum-core/CHANGELOG.md @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +# Unreleased + +- **added:** `ResponseParts::status` and `ResponseParts::status_mut` accessors, + allowing `IntoResponseParts` implementations to set the response status ([#3721]) + +[#3721]: https://github.com/tokio-rs/axum/pull/3721 + +# 0.5.6 + +Improve error messages with `#[diagnostic::do_not_recommend]`. + # 0.5.5 Released without changes to fix docs.rs build. diff --git a/axum-core/src/response/into_response_parts.rs b/axum-core/src/response/into_response_parts.rs index 55b705fc..3ce5c980 100644 --- a/axum-core/src/response/into_response_parts.rs +++ b/axum-core/src/response/into_response_parts.rs @@ -107,6 +107,18 @@ pub struct ResponseParts { } impl ResponseParts { + /// Gets the response status code. + #[must_use] + pub fn status(&self) -> StatusCode { + self.res.status() + } + + /// Gets a mutable reference to the response status code. + #[must_use] + pub fn status_mut(&mut self) -> &mut StatusCode { + self.res.status_mut() + } + /// Gets a reference to the response headers. #[must_use] pub fn headers(&self) -> &HeaderMap { diff --git a/axum/CHANGELOG.md b/axum/CHANGELOG.md index f0c6945e..04dd560d 100644 --- a/axum/CHANGELOG.md +++ b/axum/CHANGELOG.md @@ -7,9 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # Unreleased +- **added:** `IntoResponseParts` impl for `Redirect`, allowing it to be combined + with a body in a response tuple ([#3721]) - **changed:** Updated `matchit` allowing for routes with captures and static prefixes and suffixes ([#3702]) [#3702]: https://github.com/tokio-rs/axum/pull/3702 +[#3721]: https://github.com/tokio-rs/axum/pull/3721 # 0.8.9 diff --git a/axum/src/response/redirect.rs b/axum/src/response/redirect.rs index e33928cd..b408e8cd 100644 --- a/axum/src/response/redirect.rs +++ b/axum/src/response/redirect.rs @@ -1,4 +1,4 @@ -use axum_core::response::{IntoResponse, Response}; +use axum_core::response::{IntoResponse, IntoResponseParts, Response, ResponseParts}; use http::{header::LOCATION, HeaderValue, StatusCode}; /// Response that redirects the request to another location. @@ -93,11 +93,65 @@ impl IntoResponse for Redirect { } } +impl IntoResponseParts for Redirect { + type Error = (StatusCode, String); + + /// Sets the redirect status code and `Location` header on the response. + /// + /// This allows `Redirect` to be used as part of a response tuple, for example + /// to include a body alongside a redirect as recommended by + /// [RFC 9110 ยง15.4.4](https://datatracker.ietf.org/doc/html/rfc9110#name-303-see-other). + /// + /// # Examples + /// + /// ```rust + /// use axum::response::{Html, Redirect}; + /// + /// let url = "https://example.com"; + /// + /// // Return a redirect with a body + /// let response = ( + /// Redirect::to(url), + /// Html(format!( + /// r#"
Redirecting to {url}
"#, + /// )), + /// ); + /// ``` + /// + /// Note that when used alongside an explicit [`StatusCode`] in a tuple, the + /// `StatusCode` takes precedence: + /// + /// ```rust + /// use axum::response::Redirect; + /// use axum::http::StatusCode; + /// + /// // The status will be 307, not 303 + /// let response = ( + /// StatusCode::TEMPORARY_REDIRECT, + /// Redirect::to("/new"), + /// "redirecting...", + /// ); + /// ``` + fn into_response_parts(self, mut res: ResponseParts) -> Result