Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RPC context extractor #450

Closed
fracek opened this issue Sep 4, 2021 · 6 comments
Closed

RPC context extractor #450

fracek opened this issue Sep 4, 2021 · 6 comments

Comments

@fracek
Copy link

fracek commented Sep 4, 2021

I'm working on a project that needs to extract parts of the RPC context from the request. This is similar to what I can do in jsonrpc where I can register a MetaExtractor to extract the handler metadata.

If you're open to this but is not a priority, I can work on a PR for it.

@niklasad1
Copy link
Member

niklasad1 commented Sep 6, 2021

Alright, I'm not super familiar how the MetaExtractor works in jsonrpc.
Can you give an example how you want to use it?

However, sounds reasonable to me and if you want to work on it that would be really great.

@fracek
Copy link
Author

fracek commented Sep 6, 2021

At the moment I'm extracting the origin of a request with this (simplified) extractor:

#[derive(Debug, Clone)]
pub struct AppMetadata {
    pub origin: Option<HeaderValue>,
}

#[derive(Debug, Default)]
pub struct AppMetaExtractor;

impl Metadata for AppMetadata {}

impl MetaExtractor<AppMetadata> for AppMetaExtractor {
    fn read_metadata(&self, req: &Request<Body>) -> AppMetadata {
        let origin = req.headers().get("origin").cloned();
        AppMetadata { origin }
    }
}

And then hook it into the server when creating the server:

    let server = ServerBuilder::with_meta_extractor(io, AppMetaExtractor::default())
        .threads(3)
        .start_http(&"127.0.0.1:1248".parse().unwrap())?;

My plan is to change the type of jsonrpsee_utils::server::RpcModule<Context> to RpcModule<Context, Request> and add the following constructor (notice now the RpcModule is now parametrized by the request type):

pub fn new_with_context_extractor(extractor: Fn<Request> -> Context) -> RpcModule<Context, Request>

The main issue is that the same RpcModule cannot be used by an http and ws server (because the types now differ, since one will have an http request and the other a ws request). I believe that's a breaking change.

@niklasad1
Copy link
Member

//cc @maciejhirsz could maybe be solved by RPC module middleware too?!

@dvdplm dvdplm mentioned this issue Oct 1, 2021
10 tasks
@dvdplm dvdplm mentioned this issue Nov 23, 2021
7 tasks
@dvdplm
Copy link
Contributor

dvdplm commented Dec 1, 2021

@fracek We just merged #576 which adds limited support for middleware but your use case is not covered I'd say. I am skeptical about adding a second parameter to RpcModule as it would be a big and invasive change. Is there any other way we could solve this? Thinking out loud, perhaps an optional extension trait on Context that users can implement for it to gain access to metadata extraction facilities somehow?

//cc @maciejhirsz Thoughts?

@fracek
Copy link
Author

fracek commented Dec 1, 2021

Thanks for pinging me. I understand my issue is very niche, so I think the API doesn't have to be super-simple (like in the previous crate), it just needs to let me do it. I agree adding an extra type parameter is too invasive.

@niklasad1
Copy link
Member

niklasad1 commented Jun 23, 2022

We will extend the middleware to support this, see #699

TLDR; you will get:

  • WsMiddleware::on_connect(remote_addr: SocketAddr, headers: &[Header])
  • HttpMiddleware::on_call(remote_addr: SocketAddr, headers: &[Header])

Middleware is trait you can implement yourself to do custom things,

However, duplicate of #699 so closing this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants