Merge pull request #8 from jevolk/conduwuit-changes

Daily Rumanation 🤔
This commit is contained in:
June 🍓🦴 2024-08-12 19:48:17 -04:00 committed by GitHub
commit 38d791b679
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 131 additions and 41 deletions

View File

@ -7,14 +7,16 @@ pub mod v1 {
//! //!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1mediadownloadservernamemediaid //! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1mediadownloadservernamemediaid
use std::time::Duration; use std::{borrow::Cow, time::Duration};
use http::header::{CONTENT_DISPOSITION, CONTENT_TYPE}; use http::header::{CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_TYPE};
use ruma_common::{ use ruma_common::{
api::{request, response, Metadata}, api::{request, response, Metadata},
metadata, IdParseError, MxcUri, OwnedServerName, metadata, IdParseError, MxcUri, OwnedServerName,
}; };
use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY;
const METADATA: Metadata = metadata! { const METADATA: Metadata = metadata! {
method: GET, method: GET,
rate_limited: true, rate_limited: true,
@ -58,7 +60,7 @@ pub mod v1 {
/// The content type of the file that was previously uploaded. /// The content type of the file that was previously uploaded.
#[ruma_api(header = CONTENT_TYPE)] #[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 /// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
/// file that was previously uploaded. /// file that was previously uploaded.
@ -67,7 +69,23 @@ pub mod v1 {
/// ///
/// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Syntax /// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Syntax
#[ruma_api(header = CONTENT_DISPOSITION)] #[ruma_api(header = CONTENT_DISPOSITION)]
pub content_disposition: Option<String>, pub content_disposition: 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
#[ruma_api(header = CROSS_ORIGIN_RESOURCE_POLICY)]
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
#[ruma_api(header = CACHE_CONTROL)]
pub cache_control: Option<Cow<'static, str>>,
} }
impl Request { impl Request {
@ -87,7 +105,13 @@ pub mod v1 {
impl Response { impl Response {
/// Creates a new `Response` with the given file contents. /// Creates a new `Response` with the given file contents.
pub fn new(file: Vec<u8>) -> Self { pub fn new(file: Vec<u8>) -> Self {
Self { file, content_type: None, content_disposition: None } Self {
file,
content_type: None,
content_disposition: None,
cross_origin_resource_policy: None,
cache_control: None,
}
} }
} }
} }

View File

@ -7,14 +7,16 @@ pub mod v1 {
//! //!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1mediadownloadservernamemediaidfilename //! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1mediadownloadservernamemediaidfilename
use std::time::Duration; use std::{borrow::Cow, time::Duration};
use http::header::{CONTENT_DISPOSITION, CONTENT_TYPE}; use http::header::{CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_TYPE};
use ruma_common::{ use ruma_common::{
api::{request, response, Metadata}, api::{request, response, Metadata},
metadata, IdParseError, MxcUri, OwnedServerName, metadata, IdParseError, MxcUri, OwnedServerName,
}; };
use crate::http_headers::CROSS_ORIGIN_RESOURCE_POLICY;
const METADATA: Metadata = metadata! { const METADATA: Metadata = metadata! {
method: GET, method: GET,
rate_limited: true, rate_limited: true,
@ -62,7 +64,7 @@ pub mod v1 {
/// The content type of the file that was previously uploaded. /// The content type of the file that was previously uploaded.
#[ruma_api(header = CONTENT_TYPE)] #[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 /// The value of the `Content-Disposition` HTTP header, possibly containing the name of the
/// file that was previously uploaded. /// file that was previously uploaded.
@ -71,7 +73,23 @@ pub mod v1 {
/// ///
/// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Syntax /// [MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Syntax
#[ruma_api(header = CONTENT_DISPOSITION)] #[ruma_api(header = CONTENT_DISPOSITION)]
pub content_disposition: Option<String>, pub content_disposition: 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
#[ruma_api(header = CROSS_ORIGIN_RESOURCE_POLICY)]
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
#[ruma_api(header = CACHE_CONTROL)]
pub cache_control: Option<Cow<'static, str>>,
} }
impl Request { impl Request {
@ -96,7 +114,13 @@ pub mod v1 {
impl Response { impl Response {
/// Creates a new `Response` with the given file. /// Creates a new `Response` with the given file.
pub fn new(file: Vec<u8>) -> Self { pub fn new(file: Vec<u8>) -> Self {
Self { file, content_type: None, content_disposition: None } Self {
file,
content_type: None,
content_disposition: None,
cross_origin_resource_policy: None,
cache_control: None,
}
} }
} }
} }

View File

@ -7,16 +7,18 @@ pub mod v1 {
//! //!
//! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1mediathumbnailservernamemediaid //! [spec]: https://spec.matrix.org/latest/client-server-api/#get_matrixclientv1mediathumbnailservernamemediaid
use std::time::Duration; use std::{borrow::Cow, time::Duration};
use http::header::CONTENT_TYPE; use http::header::{CACHE_CONTROL, CONTENT_TYPE};
use js_int::UInt; use js_int::UInt;
use ruma_common::{ use ruma_common::{
api::{request, response, Metadata}, api::{request, response, Metadata},
metadata, IdParseError, MxcUri, OwnedServerName, metadata, IdParseError, MxcUri, OwnedServerName,
}; };
use crate::media::get_content_thumbnail::v3::Method; use crate::{
http_headers::CROSS_ORIGIN_RESOURCE_POLICY, media::get_content_thumbnail::v3::Method,
};
const METADATA: Metadata = metadata! { const METADATA: Metadata = metadata! {
method: GET, method: GET,
@ -87,7 +89,23 @@ pub mod v1 {
/// The content type of the thumbnail. /// The content type of the thumbnail.
#[ruma_api(header = CONTENT_TYPE)] #[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
#[ruma_api(header = CROSS_ORIGIN_RESOURCE_POLICY)]
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
#[ruma_api(header = CACHE_CONTROL)]
pub cache_control: Option<Cow<'static, str>>,
} }
impl Request { impl Request {
@ -122,7 +140,12 @@ pub mod v1 {
impl Response { impl Response {
/// Creates a new `Response` with the given thumbnail. /// Creates a new `Response` with the given thumbnail.
pub fn new(file: Vec<u8>) -> Self { pub fn new(file: Vec<u8>) -> Self {
Self { file, content_type: None } Self {
file,
content_type: None,
cross_origin_resource_policy: None,
cache_control: None,
}
} }
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -60,8 +60,9 @@ impl Response {
#( #cfg_attrs )* #( #cfg_attrs )*
#field_name: { #field_name: {
headers.remove(#header_name) headers.remove(#header_name)
.map(|h| h.to_str().map(|s| s.to_owned())) .map(|h| h.to_str().map(str::to_owned))
.transpose()? .transpose()?
.map(Into::into)
} }
} }
} }
@ -71,7 +72,7 @@ impl Response {
headers.remove(#header_name) headers.remove(#header_name)
.expect("response missing expected header") .expect("response missing expected header")
.to_str()? .to_str()?
.to_owned() .into()
} }
}, },
}; };

View File

@ -9,6 +9,10 @@ impl Response {
let bytes = quote! { #ruma_common::exports::bytes }; let bytes = quote! { #ruma_common::exports::bytes };
let http = quote! { #ruma_common::exports::http }; let http = quote! { #ruma_common::exports::http };
let reserve_headers = self.fields.iter().fold(0_usize, |acc, response_field| {
acc + (response_field.as_header_field().is_some() as usize)
});
let serialize_response_headers = self.fields.iter().filter_map(|response_field| { let serialize_response_headers = self.fields.iter().filter_map(|response_field| {
response_field.as_header_field().map(|(field, header_name)| { response_field.as_header_field().map(|(field, header_name)| {
let field_name = let field_name =
@ -19,10 +23,16 @@ impl Response {
if segments.last().unwrap().ident == "Option" => if segments.last().unwrap().ident == "Option" =>
{ {
quote! { quote! {
if let Some(header) = self.#field_name { if let Some(ref header) = self.#field_name {
let header = 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)?,
};
headers.insert( headers.insert(
#header_name, #header_name,
header.parse()?, header,
); );
} }
} }
@ -68,11 +78,15 @@ impl Response {
fn try_into_http_response<T: ::std::default::Default + #bytes::BufMut>( fn try_into_http_response<T: ::std::default::Default + #bytes::BufMut>(
self, self,
) -> ::std::result::Result<#http::Response<T>, #ruma_common::api::error::IntoHttpError> { ) -> ::std::result::Result<#http::Response<T>, #ruma_common::api::error::IntoHttpError> {
static APPLICATION_JSON: #http::header::HeaderValue =
#http::header::HeaderValue::from_static("application/json");
let mut resp_builder = #http::Response::builder() let mut resp_builder = #http::Response::builder()
.status(#http::StatusCode::#status_ident) .status(#http::StatusCode::#status_ident);
.header(#http::header::CONTENT_TYPE, "application/json");
if let Some(mut headers) = resp_builder.headers_mut() { if let Some(mut headers) = resp_builder.headers_mut() {
headers.reserve(1 + #reserve_headers);
headers.insert(#http::header::CONTENT_TYPE, APPLICATION_JSON.clone());
#(#serialize_response_headers)* #(#serialize_response_headers)*
} }