access request and response headers from rpc body

This commit is contained in:
Aiden McClelland
2021-07-28 16:44:15 -06:00
parent da0d08fa35
commit 1e9ded9a31
7 changed files with 153 additions and 53 deletions

View File

@@ -444,7 +444,9 @@ fn rpc_handler(
quote! { args.#field_name }
}
ParamType::Context(_) => quote! { ctx },
_ => unreachable!(),
ParamType::Request => quote! { request },
ParamType::Response => quote! { response },
ParamType::None => unreachable!(),
});
match opt {
Options::Leaf(opt) if matches!(opt.exec_ctx, ExecutionContext::CliOnly(_)) => quote! {
@@ -452,6 +454,8 @@ fn rpc_handler(
pub async fn rpc_handler#fn_generics(
_ctx: #ctx_ty,
_request: &::rpc_toolkit::command_helpers::prelude::RequestParts,
_response: &mut ::rpc_toolkit::command_helpers::prelude::ResponseParts,
method: &str,
_args: Params#param_ty_generics,
) -> Result<::rpc_toolkit::command_helpers::prelude::Value, ::rpc_toolkit::command_helpers::prelude::RpcError> {
@@ -480,6 +484,8 @@ fn rpc_handler(
pub async fn rpc_handler#fn_generics(
ctx: #ctx_ty,
request: &::rpc_toolkit::command_helpers::prelude::RequestParts,
response: &mut ::rpc_toolkit::command_helpers::prelude::ResponseParts,
method: &str,
args: Params#param_ty_generics,
) -> Result<::rpc_toolkit::command_helpers::prelude::Value, ::rpc_toolkit::command_helpers::prelude::RpcError> {
@@ -515,7 +521,7 @@ fn rpc_handler(
),
};
quote_spanned!{ subcommand.span() =>
[#subcommand::NAME, rest] => #subcommand::#rpc_handler(ctx, rest, ::rpc_toolkit::command_helpers::prelude::from_value(args.rest)?).await
[#subcommand::NAME, rest] => #subcommand::#rpc_handler(ctx, request, response, rest, ::rpc_toolkit::command_helpers::prelude::from_value(args.rest)?).await
}
});
let subcmd_impl = quote! {
@@ -550,6 +556,8 @@ fn rpc_handler(
pub async fn rpc_handler#fn_generics(
ctx: #ctx_ty,
request: &::rpc_toolkit::command_helpers::prelude::RequestParts,
response: &mut ::rpc_toolkit::command_helpers::prelude::ResponseParts,
method: &str,
args: Params#param_ty_generics,
) -> Result<::rpc_toolkit::command_helpers::prelude::Value, ::rpc_toolkit::command_helpers::prelude::RpcError> {
@@ -569,6 +577,8 @@ fn rpc_handler(
pub async fn rpc_handler#fn_generics(
ctx: #ctx_ty,
request: &::rpc_toolkit::command_helpers::prelude::RequestParts,
response: &mut ::rpc_toolkit::command_helpers::prelude::ResponseParts,
method: &str,
args: Params#param_ty_generics,
) -> Result<::rpc_toolkit::command_helpers::prelude::Value, ::rpc_toolkit::command_helpers::prelude::RpcError> {
@@ -618,7 +628,9 @@ fn cli_handler(
quote! { params.#field_name.clone() }
}
ParamType::Context(_) => quote! { ctx },
_ => unreachable!(),
ParamType::Request => quote! { request },
ParamType::Response => quote! { response },
ParamType::None => unreachable!(),
});
let mut param_generics_filter = GenericFilter::new(fn_generics);
for param in params {

View File

@@ -90,4 +90,6 @@ pub enum ParamType {
None,
Arg(ArgOptions),
Context(Type),
Request,
Response,
}

View File

@@ -666,6 +666,16 @@ pub fn parse_param_attrs(item: &mut ItemFn) -> Result<Vec<ParamType>> {
attr.span(),
"`arg` and `context` are mutually exclusive",
));
} else if matches!(ty, ParamType::Request) {
return Err(Error::new(
attr.span(),
"`arg` and `request` are mutually exclusive",
));
} else if matches!(ty, ParamType::Response) {
return Err(Error::new(
attr.span(),
"`arg` and `response` are mutually exclusive",
));
}
} else if param.attrs[i].path.is_ident("context") {
let attr = param.attrs.remove(i);
@@ -681,6 +691,66 @@ pub fn parse_param_attrs(item: &mut ItemFn) -> Result<Vec<ParamType>> {
attr.span(),
"`arg` and `context` are mutually exclusive",
));
} else if matches!(ty, ParamType::Request) {
return Err(Error::new(
attr.span(),
"`context` and `request` are mutually exclusive",
));
} else if matches!(ty, ParamType::Response) {
return Err(Error::new(
attr.span(),
"`context` and `response` are mutually exclusive",
));
}
} else if param.attrs[i].path.is_ident("request") {
let attr = param.attrs.remove(i);
if matches!(ty, ParamType::None) {
ty = ParamType::Request;
} else if matches!(ty, ParamType::Request) {
return Err(Error::new(
attr.span(),
"`request` attribute may only be specified once",
));
} else if matches!(ty, ParamType::Arg(_)) {
return Err(Error::new(
attr.span(),
"`arg` and `request` are mutually exclusive",
));
} else if matches!(ty, ParamType::Context(_)) {
return Err(Error::new(
attr.span(),
"`context` and `request` are mutually exclusive",
));
} else if matches!(ty, ParamType::Response) {
return Err(Error::new(
attr.span(),
"`request` and `response` are mutually exclusive",
));
}
} else if param.attrs[i].path.is_ident("response") {
let attr = param.attrs.remove(i);
if matches!(ty, ParamType::None) {
ty = ParamType::Response;
} else if matches!(ty, ParamType::Response) {
return Err(Error::new(
attr.span(),
"`response` attribute may only be specified once",
));
} else if matches!(ty, ParamType::Arg(_)) {
return Err(Error::new(
attr.span(),
"`arg` and `response` are mutually exclusive",
));
} else if matches!(ty, ParamType::Context(_)) {
return Err(Error::new(
attr.span(),
"`context` and `response` are mutually exclusive",
));
} else if matches!(ty, ParamType::Request) {
return Err(Error::new(
attr.span(),
"`request` and `response` are mutually exclusive",
));
}
} else {
i += 1;

View File

@@ -54,29 +54,30 @@ pub fn build(args: RpcServerArgs) -> TokenStream {
Err(res) => return Ok(res),
};
)*
let rpc_req = ::rpc_toolkit::rpc_server_helpers::make_request(&mut req).await;
let (mut req_parts, req_body) = req.into_parts();
let (mut res_parts, _) = ::rpc_toolkit::hyper::Response::new(()).into_parts();
let rpc_req = ::rpc_toolkit::rpc_server_helpers::make_request(&req_parts, req_body).await;
match rpc_req {
Ok(mut rpc_req) => {
#(
let #middleware_name_post = match #middleware_name_pre2(&mut rpc_req).await? {
let #middleware_name_post = match #middleware_name_pre2(&mut req_parts, &mut rpc_req).await? {
Ok(a) => a,
Err(res) => return Ok(res),
};
)*
let mut rpc_res = #command(
ctx,
::rpc_toolkit::yajrc::RpcMethod::as_str(&rpc_req.method),
rpc_req.params,
)
.await;
let mut rpc_res = match ::rpc_toolkit::serde_json::from_value(::rpc_toolkit::serde_json::Value::Object(rpc_req.params)) {
Ok(params) => #command(ctx, &req_parts, &mut res_parts, ::rpc_toolkit::yajrc::RpcMethod::as_str(&rpc_req.method), params).await,
Err(e) => Err(e.into())
};
#(
let #middleware_name = match #middleware_name_post_inv(&mut rpc_res).await? {
let #middleware_name = match #middleware_name_post_inv(&mut res_parts, &mut rpc_res).await? {
Ok(a) => a,
Err(res) => return Ok(res),
};
)*
let mut res = ::rpc_toolkit::rpc_server_helpers::to_response(
&req,
&req_parts.headers,
res_parts,
Ok((
rpc_req.id,
rpc_res,
@@ -89,7 +90,8 @@ pub fn build(args: RpcServerArgs) -> TokenStream {
Ok::<_, ::rpc_toolkit::hyper::http::Error>(res)
}
Err(e) => ::rpc_toolkit::rpc_server_helpers::to_response(
&req,
&req_parts.headers,
res_parts,
Err(e),
status_fn,
),