Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add uri typed headers #3455

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
11 changes: 10 additions & 1 deletion actix-http/src/header/into_value.rs
Original file line number Diff line number Diff line change
@@ -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`].
Expand Down Expand Up @@ -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, Self::Error> {
HeaderValue::from_str(&self.to_string())
}
}
keithamus marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 4 additions & 0 deletions actix-web/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
36 changes: 36 additions & 0 deletions actix-web/src/http/header/content_location.rs
Original file line number Diff line number Diff line change
@@ -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::<Uri>().unwrap())
/// );
/// ```
(ContentLocation, CONTENT_LOCATION) => [Uri]

test_parse_and_format {
crate::http::header::common_header_test!(test1, [b"http://www.example.org/hypertext/Overview.html"]);
}
}
37 changes: 37 additions & 0 deletions actix-web/src/http/header/location.rs
Original file line number Diff line number Diff line change
@@ -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::<Uri>().unwrap())
/// );
/// ```
(Location, LOCATION) => [Uri]

test_parse_and_format {
crate::http::header::common_header_test!(test1, [b"http://www.example.org/hypertext/Overview.html"]);
}
}
7 changes: 7 additions & 0 deletions actix-web/src/http/header/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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,
Expand All @@ -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`].
Expand Down
36 changes: 36 additions & 0 deletions actix-web/src/http/header/referer.rs
Original file line number Diff line number Diff line change
@@ -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::<Uri>().unwrap())
/// );
/// ```
(Referer, REFERER) => [Uri]

test_parse_and_format {
crate::http::header::common_header_test!(test1, [b"http://www.example.org/hypertext/Overview.html"]);
}
}
Loading