diff --git a/actix-http/src/header/into_value.rs b/actix-http/src/header/into_value.rs index 253900633d0..688580420a0 100644 --- a/actix-http/src/header/into_value.rs +++ b/actix-http/src/header/into_value.rs @@ -1,7 +1,7 @@ //! [`TryIntoHeaderValue`] trait and implementations. use bytes::Bytes; -use http::{header::InvalidHeaderValue, Error as HttpError, HeaderValue}; +use http::{header::InvalidHeaderValue, Error as HttpError, HeaderValue, Uri}; use mime::Mime; /// An interface for types that can be converted into a [`HeaderValue`]. @@ -129,3 +129,12 @@ impl TryIntoHeaderValue for Mime { HeaderValue::from_str(self.as_ref()) } } + +impl TryIntoHeaderValue for Uri { + type Error = InvalidHeaderValue; + + #[inline] + fn try_into_value(self) -> Result { + HeaderValue::from_str(&self.to_string()) + } +} diff --git a/actix-web/CHANGES.md b/actix-web/CHANGES.md index 36e8b62dd42..3751d11d65a 100644 --- a/actix-web/CHANGES.md +++ b/actix-web/CHANGES.md @@ -3,6 +3,10 @@ ## Unreleased - Minimum supported Rust version (MSRV) is now 1.75. +- Add `TryIntoHeaderValue` for `Uri` type. +- Add `http::header::ContentLocation` typed header. +- Add `http::header::Location` typed header. +- Add `http::header::Referer` typed header. ## 4.9.0 diff --git a/actix-web/src/http/header/content_location.rs b/actix-web/src/http/header/content_location.rs new file mode 100644 index 00000000000..9f0ea505f9f --- /dev/null +++ b/actix-web/src/http/header/content_location.rs @@ -0,0 +1,36 @@ +use super::{Uri, CONTENT_LOCATION}; + +crate::http::header::common_header! { + /// `Content-Location` header, defined + /// in [RFC 9110 §8.7](https://datatracker.ietf.org/doc/html/rfc9110#section-8.7) + /// + /// The "Content-Location" header field references a URI that can be used + /// as an identifier for a specific resource corresponding to the + /// representation in this message's content. + /// + /// # ABNF + /// ```plain + /// Content-Location = absolute-URI / partial-URI + /// ``` + /// + /// # Example Values + /// * `http://www.example.org/hypertext/Overview.html` + /// + /// # Examples + /// + /// ``` + /// use actix_web::HttpResponse; + /// use actix_http::Uri; + /// use actix_web::http::header::ContentLocation; + /// + /// let mut builder = HttpResponse::Created(); + /// builder.insert_header( + /// ContentLocation("http://www.example.org".parse::().unwrap()) + /// ); + /// ``` + (ContentLocation, CONTENT_LOCATION) => [Uri] + + test_parse_and_format { + crate::http::header::common_header_test!(test1, [b"http://www.example.org/hypertext/Overview.html"]); + } +} diff --git a/actix-web/src/http/header/location.rs b/actix-web/src/http/header/location.rs new file mode 100644 index 00000000000..3a759152ddd --- /dev/null +++ b/actix-web/src/http/header/location.rs @@ -0,0 +1,37 @@ +use super::{Uri, LOCATION}; + +crate::http::header::common_header! { + /// `Location` header, defined + /// in [RFC 9110 §10.2.2](https://datatracker.ietf.org/doc/html/rfc9110#section-10.2.2) + /// + /// The "Location" header field is used in some responses to refer to a + /// specific resource in relation to the response. The type of relationship + /// is defined by the combination of request method and status code + /// semantics. + /// + /// # ABNF + /// ```plain + /// Location = URI-reference + /// ``` + /// + /// # Example Values + /// * `http://www.example.org/hypertext/Overview.html` + /// + /// # Examples + /// + /// ``` + /// use actix_web::HttpResponse; + /// use actix_http::Uri; + /// use actix_web::http::header::Location; + /// + /// let mut builder = HttpResponse::Ok(); + /// builder.insert_header( + /// Location("http://www.example.org".parse::().unwrap()) + /// ); + /// ``` + (Location, LOCATION) => [Uri] + + test_parse_and_format { + crate::http::header::common_header_test!(test1, [b"http://www.example.org/hypertext/Overview.html"]); + } +} diff --git a/actix-web/src/http/header/mod.rs b/actix-web/src/http/header/mod.rs index 51ac4fcfd90..e0e25049dde 100644 --- a/actix-web/src/http/header/mod.rs +++ b/actix-web/src/http/header/mod.rs @@ -14,6 +14,7 @@ use std::fmt; // - the few typed headers from actix-http // - header parsing utils pub use actix_http::header::*; +use actix_http::Uri; use bytes::{Bytes, BytesMut}; mod accept; @@ -25,6 +26,7 @@ mod cache_control; mod content_disposition; mod content_language; mod content_length; +mod content_location; mod content_range; mod content_type; mod date; @@ -38,9 +40,11 @@ mod if_none_match; mod if_range; mod if_unmodified_since; mod last_modified; +mod location; mod macros; mod preference; mod range; +mod referer; #[cfg(test)] pub(crate) use self::macros::common_header_test; @@ -55,6 +59,7 @@ pub use self::{ content_disposition::{ContentDisposition, DispositionParam, DispositionType}, content_language::ContentLanguage, content_length::ContentLength, + content_location::ContentLocation, content_range::{ContentRange, ContentRangeSpec}, content_type::ContentType, date::Date, @@ -68,8 +73,10 @@ pub use self::{ if_range::IfRange, if_unmodified_since::IfUnmodifiedSince, last_modified::LastModified, + location::Location, preference::Preference, range::{ByteRangeSpec, Range}, + referer::Referer, }; /// Format writer ([`fmt::Write`]) for a [`BytesMut`]. diff --git a/actix-web/src/http/header/referer.rs b/actix-web/src/http/header/referer.rs new file mode 100644 index 00000000000..0087b10fd78 --- /dev/null +++ b/actix-web/src/http/header/referer.rs @@ -0,0 +1,36 @@ +use super::{Uri, REFERER}; + +crate::http::header::common_header! { + /// `Referer` header, defined + /// in [RFC 9110 §10.1.3](https://datatracker.ietf.org/doc/html/rfc9110#section-10.1.3) + /// + /// The "Referer" (sic) header field allows the user agent to specify a URI + /// reference for the resource from which the target URI was obtained (i.e., + /// the "referrer", though the field name is misspelled). + /// + /// # ABNF + /// ```plain + /// Referer = absolute-URI / partial-URI + /// ``` + /// + /// # Example Values + /// * `http://www.example.org/hypertext/Overview.html` + /// + /// # Examples + /// + /// ``` + /// use actix_web::HttpResponse; + /// use actix_http::Uri; + /// use actix_web::http::header::Referer; + /// + /// let mut builder = HttpResponse::Ok(); + /// builder.insert_header( + /// Referer("http://www.example.org".parse::().unwrap()) + /// ); + /// ``` + (Referer, REFERER) => [Uri] + + test_parse_and_format { + crate::http::header::common_header_test!(test1, [b"http://www.example.org/hypertext/Overview.html"]); + } +}