Revert "feat: impl IntoResponseParts for Redirect (#3721)"

This reverts commit 4eed2f6c13.
This commit is contained in:
David Pedersen
2026-05-05 15:04:03 +02:00
parent acc17a5089
commit c2bf6db649
4 changed files with 2 additions and 127 deletions
-11
View File
@@ -5,17 +5,6 @@ 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.
@@ -107,18 +107,6 @@ 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 {
-3
View File
@@ -7,12 +7,9 @@ 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
+2 -101
View File
@@ -1,4 +1,4 @@
use axum_core::response::{IntoResponse, IntoResponseParts, Response, ResponseParts};
use axum_core::response::{IntoResponse, Response};
use http::{header::LOCATION, HeaderValue, StatusCode};
/// Response that redirects the request to another location.
@@ -93,65 +93,11 @@ 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#"<p>Redirecting to <a href="{url}">{url}</a></p>"#,
/// )),
/// );
/// ```
///
/// 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<ResponseParts, Self::Error> {
let location = HeaderValue::try_from(self.location).map_err(|err| {
(
StatusCode::INTERNAL_SERVER_ERROR,
format!("invalid redirect location: {err}"),
)
})?;
*res.status_mut() = self.status_code;
res.headers_mut().insert(LOCATION, location);
Ok(res)
}
}
#[cfg(test)]
mod tests {
use super::Redirect;
use axum_core::response::IntoResponse;
use http::{header::LOCATION, StatusCode};
use http::StatusCode;
const EXAMPLE_URL: &str = "https://example.com";
@@ -189,49 +135,4 @@ mod tests {
assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);
}
#[test]
fn into_response_parts_sets_status_and_location() {
let response = (Redirect::to(EXAMPLE_URL), "body").into_response();
assert_eq!(response.status(), StatusCode::SEE_OTHER);
assert_eq!(response.headers().get(LOCATION).unwrap(), EXAMPLE_URL);
}
#[test]
fn into_response_parts_with_permanent_redirect() {
let response = (Redirect::permanent(EXAMPLE_URL), "body").into_response();
assert_eq!(response.status(), StatusCode::PERMANENT_REDIRECT);
assert_eq!(response.headers().get(LOCATION).unwrap(), EXAMPLE_URL);
}
#[test]
fn into_response_parts_with_temporary_redirect() {
let response = (Redirect::temporary(EXAMPLE_URL), "body").into_response();
assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT);
assert_eq!(response.headers().get(LOCATION).unwrap(), EXAMPLE_URL);
}
#[test]
fn into_response_parts_explicit_status_overrides() {
// Explicit StatusCode in a tuple takes precedence over the Redirect status
let response = (
StatusCode::TEMPORARY_REDIRECT,
Redirect::to(EXAMPLE_URL),
"body",
)
.into_response();
assert_eq!(response.status(), StatusCode::TEMPORARY_REDIRECT);
assert_eq!(response.headers().get(LOCATION).unwrap(), EXAMPLE_URL);
}
#[test]
fn into_response_parts_invalid_location() {
let response = (Redirect::permanent("invalid\nlocation"), "body").into_response();
assert_eq!(response.status(), StatusCode::INTERNAL_SERVER_ERROR);
}
}