implement request making
This commit is contained in:
parent
840c0b95df
commit
5743585a77
6 changed files with 77 additions and 11 deletions
|
@ -7,7 +7,7 @@ use eva::{
|
|||
|
||||
use http::Method;
|
||||
use viendesu_core::{
|
||||
errors,
|
||||
errors::{self, Aux},
|
||||
requests::Response,
|
||||
service::{
|
||||
CallStep, Session, SessionMaker,
|
||||
|
@ -97,7 +97,56 @@ impl HttpClient {
|
|||
where
|
||||
R: Request,
|
||||
{
|
||||
todo!()
|
||||
let mut endpoint = self.options.endpoint.clone();
|
||||
if endpoint.ends_with('/') {
|
||||
endpoint.push_str(path.strip_prefix('/').unwrap_or(path));
|
||||
} else {
|
||||
endpoint.push_str(path);
|
||||
}
|
||||
|
||||
let mut req = self.client.request(method.clone(), endpoint);
|
||||
if method == Method::GET {
|
||||
req = req.query(&request);
|
||||
} else {
|
||||
let mut dst = Vec::with_capacity(128);
|
||||
self.options
|
||||
.format
|
||||
.dump(Default::default(), &request, &mut dst);
|
||||
req = req
|
||||
.body(dst)
|
||||
.header("content-type", self.options.format.mime_type());
|
||||
}
|
||||
|
||||
if let Some(sess) = self.session {
|
||||
req = req.header("authorization", format!("Bearer {}", sess.to_str()));
|
||||
}
|
||||
|
||||
let response = self
|
||||
.client
|
||||
.execute(req.build().expect("shit happens"))
|
||||
.await
|
||||
.map_err(|e| Aux::InternalError(format_compact!("failed to make request: {e:#}")))?;
|
||||
let bytes = response
|
||||
.bytes()
|
||||
.await
|
||||
.map_err(|e| Aux::InternalError(format_compact!("failed to read bytes: {e:#}")))?;
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum GenericResponse<O, E> {
|
||||
Success { ok: O },
|
||||
Error { error: errors::Generic<E> },
|
||||
}
|
||||
|
||||
let resp: GenericResponse<R::Response, R::Error> =
|
||||
self.options.format.load(&bytes).map_err(|e| {
|
||||
Aux::Deserialization(format!("failed to deserialize response: {e:#}"))
|
||||
})?;
|
||||
|
||||
match resp {
|
||||
GenericResponse::Error { error } => Err(error),
|
||||
GenericResponse::Success { ok } => Ok(ok),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
pub mod status_code;
|
||||
|
||||
pub trait Request: Send + Sync + 'static + for<'de> serde::Deserialize<'de> {
|
||||
pub trait Request:
|
||||
Send + Sync + 'static + for<'de> serde::Deserialize<'de> + serde::Serialize
|
||||
{
|
||||
type Response: IsResponse;
|
||||
type Error: IsResponse;
|
||||
}
|
||||
|
||||
eva::trait_set! {
|
||||
pub trait IsResponse = status_code::HasStatusCode + serde::Serialize + Send + Sync + 'static;
|
||||
pub trait IsResponse = status_code::HasStatusCode + for<'de> serde::Deserialize<'de> + serde::Serialize + Send + Sync + 'static;
|
||||
}
|
||||
|
||||
macro_rules! impl_req {
|
||||
|
|
|
@ -43,8 +43,6 @@ pub async fn load_args<R: ServerRequest>(req: AxumRequest) -> Result<Context<R>,
|
|||
|
||||
let response_format =
|
||||
extract::response_format(&parts).map_err(|e| response::err(Format::default(), e))?;
|
||||
let request_format =
|
||||
extract::request_format(&parts).map_err(|e| response::err(Format::default(), e))?;
|
||||
|
||||
let request: R = if parts.method == Method::GET {
|
||||
let query = parts.uri.query().unwrap_or("");
|
||||
|
@ -52,6 +50,8 @@ pub async fn load_args<R: ServerRequest>(req: AxumRequest) -> Result<Context<R>,
|
|||
.map_err(|e| Aux::Deserialization(format!("failed to decode query: {e}")))
|
||||
.map_err(|e| response::err(response_format, e))?
|
||||
} else {
|
||||
let request_format =
|
||||
extract::request_format(&parts).map_err(|e| response::err(response_format, e))?;
|
||||
let content_length =
|
||||
extract::content_length(&parts).map_err(|e| response::err(response_format, e))?;
|
||||
let mut data_stream = body.into_data_stream();
|
||||
|
|
|
@ -9,7 +9,10 @@ use axum::{
|
|||
routing::{MethodFilter, method_routing},
|
||||
};
|
||||
|
||||
use viendesu_core::{errors as core_errors, service::SessionOf};
|
||||
use viendesu_core::{
|
||||
errors as core_errors,
|
||||
service::{Session, SessionOf, authz::AuthenticationMut},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
format::Format,
|
||||
|
@ -118,11 +121,21 @@ impl<R: ServerRequest, M, T: Types, Cx: MakeContext<R>> FinishedHandler<R, M, T,
|
|||
let (parts, body) = req.into_parts();
|
||||
let context = make_context(AxumRequest::from_parts(parts, body)).await?;
|
||||
let resp_format = context.response_format;
|
||||
let session = state
|
||||
let mut session = state
|
||||
.make_session()
|
||||
.await
|
||||
.map_err(|e| response::err(resp_format, e))?;
|
||||
|
||||
if let Some(token) = extract::session_token(&context.parts)
|
||||
.map_err(|e| response::err(resp_format, e))?
|
||||
{
|
||||
session
|
||||
.authentication_mut()
|
||||
.authenticate(token)
|
||||
.await
|
||||
.map_err(|e| response::err(resp_format, e))?;
|
||||
}
|
||||
|
||||
match make_request(session, context).await {
|
||||
Ok(r) => Ok(response::ok(resp_format, r)),
|
||||
Err(e) => Err(response::err(resp_format, e)),
|
||||
|
|
|
@ -48,6 +48,8 @@ pub fn session_token(parts: &Parts) -> AuxResult<Option<session::Token>> {
|
|||
)));
|
||||
};
|
||||
|
||||
dbg!((scheme, rest));
|
||||
|
||||
match scheme {
|
||||
"Bearer" => rest
|
||||
.parse()
|
||||
|
|
|
@ -2,7 +2,7 @@ use axum::{
|
|||
http::StatusCode,
|
||||
response::{IntoResponse, Response as AxumResponse},
|
||||
};
|
||||
use serde::Serialize;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
use crate::format::{DumpParams, Format};
|
||||
use crate::requests::{IsResponse, status_code::HasStatusCode};
|
||||
|
@ -18,7 +18,7 @@ macro_rules! header {
|
|||
|
||||
#[track_caller]
|
||||
pub fn err<E: IsResponse>(format: Format, error: E) -> AxumResponse {
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Failure<E> {
|
||||
pub error: E,
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ pub fn err<E: IsResponse>(format: Format, error: E) -> AxumResponse {
|
|||
|
||||
#[track_caller]
|
||||
pub fn ok<O: IsResponse>(format: Format, ok: O) -> AxumResponse {
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Success<T> {
|
||||
ok: T,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue