Revert "Revert "optimize for optional static response headers zero-copy zero-alloc""

This reverts commit 6bdc5ad326029e84fe05ed2591d9ba442bab8ff5.

Revert "Revert "Fix assumptions about header value types""

This reverts commit 03037f6c92ffb43388022d288e5a36f20a8559dd.
This commit is contained in:
Jason Volk 2024-08-15 03:28:05 +00:00
parent 6e5e96cba3
commit 3f06ade0fd
11 changed files with 109 additions and 55 deletions

View File

@ -7,7 +7,7 @@ pub mod v1 {
//!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1mediadownloadservernamemediaid
use std::time::Duration;
use std::{borrow::Cow, time::Duration};
use http::header::{CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_TYPE};
use ruma_common::{
@ -61,7 +61,7 @@ pub mod v1 {
/// The content type of the file that was previously uploaded.
#[ruma_api(header = CONTENT_TYPE)]
pub content_type: Option<String>,
pub content_type: Option<Cow<'static, str>>,
/// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
/// file that was previously uploaded.
@ -76,7 +76,7 @@ pub mod v1 {
///
/// TODO: make this use Cow static str's
#[ruma_api(header = CROSS_ORIGIN_RESOURCE_POLICY)]
pub cross_origin_resource_policy: Option<String>,
pub cross_origin_resource_policy: Option<Cow<'static, str>>,
/// The value of the `Cache-Control` HTTP header.
///
@ -86,7 +86,7 @@ pub mod v1 {
///
/// TODO: make this use Cow static str's
#[ruma_api(header = CACHE_CONTROL)]
pub cache_control: Option<String>,
pub cache_control: Option<Cow<'static, str>>,
}
impl Request {

View File

@ -7,7 +7,7 @@ pub mod v1 {
//!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1mediadownloadservernamemediaidfilename
use std::time::Duration;
use std::{borrow::Cow, time::Duration};
use http::header::{CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_TYPE};
use ruma_common::{
@ -65,7 +65,7 @@ pub mod v1 {
/// The content type of the file that was previously uploaded.
#[ruma_api(header = CONTENT_TYPE)]
pub content_type: Option<String>,
pub content_type: Option<Cow<'static, str>>,
/// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
/// file that was previously uploaded.
@ -80,7 +80,7 @@ pub mod v1 {
///
/// TODO: make this use Cow static str's
#[ruma_api(header = CROSS_ORIGIN_RESOURCE_POLICY)]
pub cross_origin_resource_policy: Option<String>,
pub cross_origin_resource_policy: Option<Cow<'static, str>>,
/// The value of the `Cache-Control` HTTP header.
///
@ -90,7 +90,7 @@ pub mod v1 {
///
/// TODO: make this use Cow static str's
#[ruma_api(header = CACHE_CONTROL)]
pub cache_control: Option<String>,
pub cache_control: Option<Cow<'static, str>>,
}
impl Request {

View File

@ -7,7 +7,7 @@ pub mod v1 {
//!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1mediathumbnailservernamemediaid
use std::time::Duration;
use std::{borrow::Cow, time::Duration};
use http::header::{CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_TYPE};
use js_int::UInt;
@ -89,27 +89,23 @@ pub mod v1 {
/// The content type of the thumbnail.
#[ruma_api(header = CONTENT_TYPE)]
pub content_type: Option<String>,
pub content_type: Option<Cow<'static, str>>,
/// The value of the `Cross-Origin-Resource-Policy` HTTP header.
///
/// See [MDN] for the syntax.
///
/// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy#syntax
///
/// TODO: make this use Cow static str's
#[ruma_api(header = CROSS_ORIGIN_RESOURCE_POLICY)]
pub cross_origin_resource_policy: Option<String>,
pub cross_origin_resource_policy: Option<Cow<'static, str>>,
/// The value of the `Cache-Control` HTTP header.
///
/// See [MDN] for the syntax.
///
/// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#syntax
///
/// TODO: make this use Cow static str's
#[ruma_api(header = CACHE_CONTROL)]
pub cache_control: Option<String>,
pub cache_control: Option<Cow<'static, str>>,
/// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
/// file that was previously uploaded.

View File

@ -7,7 +7,7 @@ pub mod v3 {
//!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixmediav3downloadservernamemediaid
use std::time::Duration;
use std::{borrow::Cow, time::Duration};
use http::header::{CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_TYPE};
use ruma_common::{
@ -84,7 +84,7 @@ pub mod v3 {
/// The content type of the file that was previously uploaded.
#[ruma_api(header = CONTENT_TYPE)]
pub content_type: Option<String>,
pub content_type: Option<Cow<'static, str>>,
/// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
/// file that was previously uploaded.
@ -97,7 +97,7 @@ pub mod v3 {
///
/// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy#syntax
#[ruma_api(header = CROSS_ORIGIN_RESOURCE_POLICY)]
pub cross_origin_resource_policy: Option<String>,
pub cross_origin_resource_policy: Option<Cow<'static, str>>,
/// The value of the `Cache-Control` HTTP header.
///
@ -105,7 +105,7 @@ pub mod v3 {
///
/// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#syntax
#[ruma_api(header = CACHE_CONTROL)]
pub cache_control: Option<String>,
pub cache_control: Option<Cow<'static, str>>,
}
#[allow(deprecated)]
@ -138,7 +138,7 @@ pub mod v3 {
file,
content_type: None,
content_disposition: None,
cross_origin_resource_policy: Some("cross-origin".to_owned()),
cross_origin_resource_policy: Some("cross-origin".into()),
cache_control: None,
}
}

View File

@ -7,7 +7,7 @@ pub mod v3 {
//!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixmediav3downloadservernamemediaidfilename
use std::time::Duration;
use std::{borrow::Cow, time::Duration};
use http::header::{CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_TYPE};
use ruma_common::{
@ -88,7 +88,7 @@ pub mod v3 {
/// The content type of the file that was previously uploaded.
#[ruma_api(header = CONTENT_TYPE)]
pub content_type: Option<String>,
pub content_type: Option<Cow<'static, str>>,
/// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
/// file that was previously uploaded.
@ -101,7 +101,7 @@ pub mod v3 {
///
/// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy#syntax
#[ruma_api(header = CROSS_ORIGIN_RESOURCE_POLICY)]
pub cross_origin_resource_policy: Option<String>,
pub cross_origin_resource_policy: Option<Cow<'static, str>>,
/// The value of the `Cache-Control` HTTP header.
///
@ -109,7 +109,7 @@ pub mod v3 {
///
/// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#syntax
#[ruma_api(header = CACHE_CONTROL)]
pub cache_control: Option<String>,
pub cache_control: Option<Cow<'static, str>>,
}
#[allow(deprecated)]
@ -143,7 +143,7 @@ pub mod v3 {
file,
content_type: None,
content_disposition: None,
cross_origin_resource_policy: Some("cross-origin".to_owned()),
cross_origin_resource_policy: Some("cross-origin".into()),
cache_control: None,
}
}

View File

@ -7,7 +7,7 @@ pub mod v3 {
//!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixmediav3thumbnailservernamemediaid
use std::time::Duration;
use std::{borrow::Cow, time::Duration};
use http::header::{CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_TYPE};
use js_int::UInt;
@ -112,7 +112,7 @@ pub mod v3 {
/// The content type of the thumbnail.
#[ruma_api(header = CONTENT_TYPE)]
pub content_type: Option<String>,
pub content_type: Option<Cow<'static, str>>,
/// The value of the `Cross-Origin-Resource-Policy` HTTP header.
///
@ -120,7 +120,7 @@ pub mod v3 {
///
/// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Resource-Policy#syntax
#[ruma_api(header = CROSS_ORIGIN_RESOURCE_POLICY)]
pub cross_origin_resource_policy: Option<String>,
pub cross_origin_resource_policy: Option<Cow<'static, str>>,
/// The value of the `Cache-Control` HTTP header.
///
@ -128,7 +128,7 @@ pub mod v3 {
///
/// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#syntax
#[ruma_api(header = CACHE_CONTROL)]
pub cache_control: Option<String>,
pub cache_control: Option<Cow<'static, str>>,
/// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
/// file that was previously uploaded.
@ -180,7 +180,7 @@ pub mod v3 {
Self {
file,
content_type: None,
cross_origin_resource_policy: Some("cross-origin".to_owned()),
cross_origin_resource_policy: Some("cross-origin".into()),
cache_control: None,
content_disposition: None,
}

View File

@ -5,6 +5,8 @@ pub mod v3 {
//!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv3loginssoredirect
use std::borrow::Cow;
use http::header::{LOCATION, SET_COOKIE};
use ruma_common::{
api::{request, response, Metadata},
@ -40,7 +42,7 @@ pub mod v3 {
/// Cookie storing state to secure the SSO process.
#[ruma_api(header = SET_COOKIE)]
pub cookie: Option<String>,
pub cookie: Option<Cow<'static, str>>,
}
impl Request {

View File

@ -7,6 +7,8 @@ pub mod v3 {
//!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv3loginssoredirectidpid
use std::borrow::Cow;
use http::header::{LOCATION, SET_COOKIE};
use ruma_common::{
api::{request, response, Metadata},
@ -46,7 +48,7 @@ pub mod v3 {
/// Cookie storing state to secure the SSO process.
#[ruma_api(header = SET_COOKIE)]
pub cookie: Option<String>,
pub cookie: Option<Cow<'static, str>>,
}
impl Request {

View File

@ -2,6 +2,7 @@
use std::{fmt, ops::Deref, str::FromStr};
use http::header::{HeaderValue, InvalidHeaderValue};
use ruma_macros::{
AsRefStr, AsStrAsRefStr, DebugAsRefStr, DisplayAsRefStr, OrdAsRefStr, PartialOrdAsRefStr,
};
@ -70,6 +71,14 @@ impl fmt::Display for ContentDisposition {
}
}
impl TryFrom<&ContentDisposition> for HeaderValue {
type Error = InvalidHeaderValue;
fn try_from(cd: &ContentDisposition) -> Result<Self, Self::Error> {
HeaderValue::from_str(cd.to_string().as_str())
}
}
impl TryFrom<&[u8]> for ContentDisposition {
type Error = ContentDispositionParseError;

View File

@ -64,11 +64,25 @@ impl Response {
let syn::GenericArgument::Type(field_type) = option_args.first().unwrap() else {
panic!("Option brackets should contain type");
};
quote! {
#( #cfg_attrs )*
#field_name: {
headers.remove(#header_name)
.and_then(|h| { h.to_str().ok()?.parse::<#field_type>().ok() })
let syn::Type::Path(syn::TypePath { path: syn::Path { segments, .. }, .. }) = field_type else {
panic!("Option type should have a path")
};
let ident = &segments.last().expect("Option type should have path segments").ident;
if ident == "Cow" {
quote! {
#( #cfg_attrs )*
#field_name: {
headers.remove(#header_name)
.map(|h| h.to_str().map(str::to_owned)).transpose()?.map(Into::into)
}
}
} else {
quote! {
#( #cfg_attrs )*
#field_name: {
headers.remove(#header_name)
.and_then(|h| { h.to_str().ok()?.parse::<#field_type>().ok() })
}
}
}
}
@ -84,6 +98,7 @@ impl Response {
.to_str()?
.parse::<#field_type>()
.map_err(|e| #ruma_common::api::error::HeaderDeserializationError::InvalidHeader(e.into()))?
.into()
}
}
}

View File

@ -20,24 +20,54 @@ impl Response {
match &field.ty {
syn::Type::Path(syn::TypePath { path: syn::Path { segments, .. }, .. })
if segments.last().unwrap().ident == "Option" =>
{
quote! {
if let Some(header) = self.#field_name {
headers.insert(
#header_name,
header.to_string().parse()?,
);
if segments.last().unwrap().ident == "Option" => {
let syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments {
args: option_args, ..
}) = &segments.last().unwrap().arguments else {
panic!("Option should use angle brackets");
};
let syn::GenericArgument::Type(field_type) = option_args.first().unwrap() else {
panic!("Option brackets should contain type");
};
let syn::Type::Path(syn::TypePath { path: syn::Path { segments, .. }, .. }) = field_type else {
panic!("Option type should have a path")
};
let ident = &segments.last().expect("Option type should have path segments").ident;
match ident.to_string().as_str() {
"Cow" => {
quote! {
if let Some(ref header) = self.#field_name {
headers.insert(
#header_name,
match header {
::std::borrow::Cow::Borrowed(ref header) =>
#http::header::HeaderValue::from_static(header),
::std::borrow::Cow::Owned(ref header) =>
#http::header::HeaderValue::from_str(&header)?,
},
);
}
}
},
"ContentDisposition" | _ => {
quote! {
if let Some(ref header) = self.#field_name {
headers.insert(
#header_name,
header.try_into()?,
);
}
}
},
}
}
}
_ => quote! {
headers.insert(
#header_name,
self.#field_name.to_string().parse()?,
);
},
}
},
_ => quote! {
headers.insert(
#header_name,
self.#field_name.try_into()?,
);
},
}
})
});