api: Stop storing the http::Request in RequestDeserializationError
This commit is contained in:
parent
2ac020173b
commit
6f5c1ee953
@ -304,7 +304,7 @@ impl Request {
|
|||||||
body => body,
|
body => body,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ruma_api::try_deserialize!(request, #serde_json::from_slice(json))
|
#serde_json::from_slice(json)?
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -330,14 +330,11 @@ impl Request {
|
|||||||
_ => (
|
_ => (
|
||||||
quote! { str_value.to_owned() },
|
quote! { str_value.to_owned() },
|
||||||
quote! {
|
quote! {
|
||||||
// FIXME: Not a missing json field, a missing header!
|
return Err(
|
||||||
return Err(#ruma_api::error::RequestDeserializationError::new(
|
|
||||||
#ruma_api::error::HeaderDeserializationError::MissingHeader(
|
#ruma_api::error::HeaderDeserializationError::MissingHeader(
|
||||||
#header_name_string.into()
|
#header_name_string.into()
|
||||||
),
|
).into(),
|
||||||
request,
|
|
||||||
)
|
)
|
||||||
.into())
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@ -345,8 +342,7 @@ impl Request {
|
|||||||
quote! {
|
quote! {
|
||||||
#field_name: match headers.get(#http::header::#header_name) {
|
#field_name: match headers.get(#http::header::#header_name) {
|
||||||
Some(header_value) => {
|
Some(header_value) => {
|
||||||
let str_value =
|
let str_value = header_value.to_str()?;
|
||||||
#ruma_api::try_deserialize!(request, header_value.to_str());
|
|
||||||
#some_case
|
#some_case
|
||||||
}
|
}
|
||||||
None => #none_case,
|
None => #none_case,
|
||||||
@ -604,22 +600,16 @@ impl Request {
|
|||||||
|
|
||||||
if self.query_map_field().is_some() {
|
if self.query_map_field().is_some() {
|
||||||
quote! {
|
quote! {
|
||||||
let request_query = #ruma_api::try_deserialize!(
|
let request_query = #ruma_serde::urlencoded::from_str(
|
||||||
request,
|
&request.uri().query().unwrap_or(""),
|
||||||
#ruma_serde::urlencoded::from_str(
|
)?;
|
||||||
&request.uri().query().unwrap_or("")
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if self.has_query_fields() {
|
} else if self.has_query_fields() {
|
||||||
quote! {
|
quote! {
|
||||||
let request_query: <RequestQuery as #ruma_serde::Outgoing>::Incoming =
|
let request_query: <RequestQuery as #ruma_serde::Outgoing>::Incoming =
|
||||||
#ruma_api::try_deserialize!(
|
|
||||||
request,
|
|
||||||
#ruma_serde::urlencoded::from_str(
|
#ruma_serde::urlencoded::from_str(
|
||||||
&request.uri().query().unwrap_or("")
|
&request.uri().query().unwrap_or("")
|
||||||
),
|
)?;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TokenStream::new()
|
TokenStream::new()
|
||||||
@ -741,16 +731,10 @@ impl Request {
|
|||||||
quote! {
|
quote! {
|
||||||
#path_var_ident: {
|
#path_var_ident: {
|
||||||
let segment = path_segments[#i].as_bytes();
|
let segment = path_segments[#i].as_bytes();
|
||||||
let decoded = #ruma_api::try_deserialize!(
|
let decoded =
|
||||||
request,
|
#percent_encoding::percent_decode(segment).decode_utf8()?;
|
||||||
#percent_encoding::percent_decode(segment)
|
|
||||||
.decode_utf8(),
|
|
||||||
);
|
|
||||||
|
|
||||||
#ruma_api::try_deserialize!(
|
::std::convert::TryFrom::try_from(&*decoded)?
|
||||||
request,
|
|
||||||
::std::convert::TryFrom::try_from(&*decoded),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -65,7 +65,7 @@ pub enum IntoHttpError {
|
|||||||
pub enum FromHttpRequestError {
|
pub enum FromHttpRequestError {
|
||||||
/// Deserialization failed
|
/// Deserialization failed
|
||||||
#[error("deserialization failed: {0}")]
|
#[error("deserialization failed: {0}")]
|
||||||
Deserialization(#[from] RequestDeserializationError),
|
Deserialization(RequestDeserializationError),
|
||||||
|
|
||||||
/// HTTP method mismatch
|
/// HTTP method mismatch
|
||||||
#[error("http method mismatch: expected {expected}, received: {received}")]
|
#[error("http method mismatch: expected {expected}, received: {received}")]
|
||||||
@ -77,22 +77,28 @@ pub enum FromHttpRequestError {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> From<T> for FromHttpRequestError
|
||||||
|
where
|
||||||
|
T: Into<RequestDeserializationError>,
|
||||||
|
{
|
||||||
|
fn from(err: T) -> Self {
|
||||||
|
Self::Deserialization(err.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An error that occurred when trying to deserialize a request.
|
/// An error that occurred when trying to deserialize a request.
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
#[error("{inner}")]
|
#[error("{inner}")]
|
||||||
pub struct RequestDeserializationError {
|
pub struct RequestDeserializationError {
|
||||||
inner: DeserializationError,
|
inner: DeserializationError,
|
||||||
http_request: http::Request<Vec<u8>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RequestDeserializationError {
|
impl<T> From<T> for RequestDeserializationError
|
||||||
/// Creates a new `RequestDeserializationError` from the given deserialization error and http
|
where
|
||||||
/// request.
|
T: Into<DeserializationError>,
|
||||||
pub fn new(
|
{
|
||||||
inner: impl Into<DeserializationError>,
|
fn from(err: T) -> Self {
|
||||||
http_request: http::Request<Vec<u8>>,
|
Self { inner: err.into() }
|
||||||
) -> Self {
|
|
||||||
Self { inner: inner.into(), http_request }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,17 +363,3 @@ pub struct Metadata {
|
|||||||
/// What authentication scheme the server uses for this endpoint.
|
/// What authentication scheme the server uses for this endpoint.
|
||||||
pub authentication: AuthScheme,
|
pub authentication: AuthScheme,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! try_deserialize {
|
|
||||||
($kind:ident, $call:expr $(,)?) => {
|
|
||||||
$crate::try_deserialize!(@$kind, $kind, $call)
|
|
||||||
};
|
|
||||||
(@request, $kind:ident, $call:expr) => {
|
|
||||||
match $call {
|
|
||||||
Ok(val) => val,
|
|
||||||
Err(err) => return Err($crate::error::RequestDeserializationError::new(err, $kind).into()),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
@ -6,8 +6,7 @@ use bytes::Buf;
|
|||||||
use http::{header::CONTENT_TYPE, method::Method};
|
use http::{header::CONTENT_TYPE, method::Method};
|
||||||
use ruma_api::{
|
use ruma_api::{
|
||||||
error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError, ServerError, Void},
|
error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError, ServerError, Void},
|
||||||
try_deserialize, AuthScheme, EndpointError, IncomingRequest, IncomingResponse, Metadata,
|
AuthScheme, EndpointError, IncomingRequest, IncomingResponse, Metadata, OutgoingRequest,
|
||||||
OutgoingRequest,
|
|
||||||
};
|
};
|
||||||
use ruma_identifiers::{RoomAliasId, RoomId};
|
use ruma_identifiers::{RoomAliasId, RoomId};
|
||||||
use ruma_serde::Outgoing;
|
use ruma_serde::Outgoing;
|
||||||
@ -70,19 +69,16 @@ impl IncomingRequest for Request {
|
|||||||
fn try_from_http_request(
|
fn try_from_http_request(
|
||||||
request: http::Request<Vec<u8>>,
|
request: http::Request<Vec<u8>>,
|
||||||
) -> Result<Self, FromHttpRequestError> {
|
) -> Result<Self, FromHttpRequestError> {
|
||||||
let request_body: RequestBody =
|
let request_body: RequestBody = serde_json::from_slice(request.body().as_slice())?;
|
||||||
try_deserialize!(request, serde_json::from_slice(request.body().as_slice()));
|
|
||||||
let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
|
let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
|
||||||
|
|
||||||
Ok(Request {
|
Ok(Request {
|
||||||
room_id: request_body.room_id,
|
room_id: request_body.room_id,
|
||||||
room_alias: {
|
room_alias: {
|
||||||
let decoded = try_deserialize!(
|
let decoded =
|
||||||
request,
|
percent_encoding::percent_decode(path_segments[5].as_bytes()).decode_utf8()?;
|
||||||
percent_encoding::percent_decode(path_segments[5].as_bytes()).decode_utf8(),
|
|
||||||
);
|
|
||||||
|
|
||||||
try_deserialize!(request, TryFrom::try_from(&*decoded))
|
TryFrom::try_from(&*decoded)?
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -109,37 +109,30 @@ impl ruma_api::IncomingRequest for IncomingRequest {
|
|||||||
) -> Result<Self, ruma_api::error::FromHttpRequestError> {
|
) -> Result<Self, ruma_api::error::FromHttpRequestError> {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use ruma_api::try_deserialize;
|
use ruma_events::EventContent as _;
|
||||||
use ruma_events::EventContent;
|
|
||||||
use serde_json::value::RawValue as RawJsonValue;
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
|
|
||||||
let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
|
let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
|
||||||
|
|
||||||
let room_id = {
|
let room_id = {
|
||||||
let decoded = try_deserialize!(
|
let decoded =
|
||||||
request,
|
percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8()?;
|
||||||
percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8(),
|
|
||||||
);
|
|
||||||
|
|
||||||
try_deserialize!(request, RoomId::try_from(&*decoded))
|
RoomId::try_from(&*decoded)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let txn_id = try_deserialize!(
|
let txn_id = percent_encoding::percent_decode(path_segments[7].as_bytes())
|
||||||
request,
|
.decode_utf8()?
|
||||||
percent_encoding::percent_decode(path_segments[7].as_bytes()).decode_utf8(),
|
|
||||||
)
|
|
||||||
.into_owned();
|
.into_owned();
|
||||||
|
|
||||||
let content = {
|
let content = {
|
||||||
let request_body: Box<RawJsonValue> =
|
let request_body: Box<RawJsonValue> =
|
||||||
try_deserialize!(request, serde_json::from_slice(request.body().as_slice()));
|
serde_json::from_slice(request.body().as_slice())?;
|
||||||
|
|
||||||
let event_type = try_deserialize!(
|
let event_type =
|
||||||
request,
|
percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8()?;
|
||||||
percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8()
|
|
||||||
);
|
|
||||||
|
|
||||||
try_deserialize!(request, AnyMessageEventContent::from_parts(&event_type, request_body))
|
AnyMessageEventContent::from_parts(&event_type, request_body)?
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self { room_id, txn_id, content })
|
Ok(Self { room_id, txn_id, content })
|
||||||
|
@ -113,36 +113,27 @@ impl ruma_api::IncomingRequest for IncomingRequest {
|
|||||||
) -> Result<Self, ruma_api::error::FromHttpRequestError> {
|
) -> Result<Self, ruma_api::error::FromHttpRequestError> {
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use ruma_api::try_deserialize;
|
|
||||||
|
|
||||||
let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
|
let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
|
||||||
|
|
||||||
let room_id = {
|
let room_id = {
|
||||||
let decoded = try_deserialize!(
|
let decoded =
|
||||||
request,
|
percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8()?;
|
||||||
percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8()
|
|
||||||
);
|
|
||||||
|
|
||||||
try_deserialize!(request, RoomId::try_from(&*decoded))
|
RoomId::try_from(&*decoded)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let event_type = {
|
let event_type = {
|
||||||
let decoded = try_deserialize!(
|
let decoded =
|
||||||
request,
|
percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8()?;
|
||||||
percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8()
|
|
||||||
);
|
|
||||||
|
|
||||||
try_deserialize!(request, EventType::try_from(&*decoded))
|
EventType::try_from(&*decoded)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let state_key = match path_segments.get(7) {
|
let state_key = match path_segments.get(7) {
|
||||||
Some(segment) => {
|
Some(segment) => {
|
||||||
let decoded = try_deserialize!(
|
let decoded = percent_encoding::percent_decode(segment.as_bytes()).decode_utf8()?;
|
||||||
request,
|
|
||||||
percent_encoding::percent_decode(segment.as_bytes()).decode_utf8()
|
|
||||||
);
|
|
||||||
|
|
||||||
try_deserialize!(request, String::try_from(&*decoded))
|
String::try_from(&*decoded)?
|
||||||
}
|
}
|
||||||
None => "".into(),
|
None => "".into(),
|
||||||
};
|
};
|
||||||
|
@ -111,42 +111,35 @@ impl ruma_api::IncomingRequest for IncomingRequest {
|
|||||||
fn try_from_http_request(
|
fn try_from_http_request(
|
||||||
request: http::Request<Vec<u8>>,
|
request: http::Request<Vec<u8>>,
|
||||||
) -> Result<Self, ruma_api::error::FromHttpRequestError> {
|
) -> Result<Self, ruma_api::error::FromHttpRequestError> {
|
||||||
use std::convert::TryFrom;
|
use std::{borrow::Cow, convert::TryFrom};
|
||||||
|
|
||||||
use ruma_api::try_deserialize;
|
|
||||||
use ruma_events::EventContent;
|
use ruma_events::EventContent;
|
||||||
use serde_json::value::RawValue as RawJsonValue;
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
|
|
||||||
let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
|
let path_segments: Vec<&str> = request.uri().path()[1..].split('/').collect();
|
||||||
|
|
||||||
let room_id = {
|
let room_id = {
|
||||||
let decoded = try_deserialize!(
|
let decoded =
|
||||||
request,
|
percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8()?;
|
||||||
percent_encoding::percent_decode(path_segments[4].as_bytes()).decode_utf8()
|
|
||||||
);
|
|
||||||
|
|
||||||
try_deserialize!(request, RoomId::try_from(&*decoded))
|
RoomId::try_from(&*decoded)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let state_key = match path_segments.get(7) {
|
let state_key = path_segments
|
||||||
Some(segment) => try_deserialize!(
|
.get(7)
|
||||||
request,
|
.map(|segment| percent_encoding::percent_decode(segment.as_bytes()).decode_utf8())
|
||||||
percent_encoding::percent_decode(segment.as_bytes()).decode_utf8()
|
.transpose()?
|
||||||
)
|
.unwrap_or(Cow::Borrowed(""))
|
||||||
.into_owned(),
|
.into_owned();
|
||||||
None => "".into(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let content = {
|
let content = {
|
||||||
let request_body: Box<RawJsonValue> =
|
let request_body: Box<RawJsonValue> =
|
||||||
try_deserialize!(request, serde_json::from_slice(request.body().as_slice()));
|
serde_json::from_slice(request.body().as_slice())?;
|
||||||
|
|
||||||
let event_type = try_deserialize!(
|
let event_type =
|
||||||
request,
|
percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8()?;
|
||||||
percent_encoding::percent_decode(path_segments[6].as_bytes()).decode_utf8()
|
|
||||||
);
|
|
||||||
|
|
||||||
try_deserialize!(request, AnyStateEventContent::from_parts(&event_type, request_body))
|
AnyStateEventContent::from_parts(&event_type, request_body)?
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Self { room_id, state_key, content })
|
Ok(Self { room_id, state_key, content })
|
||||||
|
Loading…
x
Reference in New Issue
Block a user