plabayo / rama

modular service framework to move and transform network packets
https://ramaproxy.org
Apache License 2.0
189 stars 20 forks source link

expand support to hijack based on context data #328

Closed GlenDC closed 3 weeks ago

GlenDC commented 1 month ago

e.g. callback, or Eq Value (e.g. UserID), stuff like that

GlenDC commented 1 month ago

Could be called an ExtensionMatcher, which can be created with two inputs:

calebbourg commented 4 weeks ago

Hello @GlenDC I would like to pick this up if it has not already been spoken for.

GlenDC commented 4 weeks ago

All yours if you want to go for it @calebbourg , welcome and nice to e-meet you.

Feel free to open a PR in any state, in case you want me to provide early feedback, or need guidance. Should the information not be clear or you might have any questions do let me know. I'm here for you.

calebbourg commented 4 weeks ago

@GlenDC Thank you very much. Yes, could you elaborate a bit on what is desired here? Perhaps point to the correct part of the project to get started?

GlenDC commented 4 weeks ago

In rama there is a Matcher interface for which you can find docs at https://ramaproxy.org/docs/rama/matcher/trait.Matcher.html

It can be used for all kinds of purposes, but for example the Hijack layer (https://ramaproxy.org/docs/rama/layer/struct.HijackLayer.html) also uses this to decide when to use the hijack service and when the regular inner server.

There are some use cases on which you might just want to match based on an extension, be it equality or with a custom callback, that are pretty easy to serve with a Matcher implementation for a new struct that you'll introduce called ExtensionMatcher. Can be added at https://github.com/plabayo/rama/tree/main/rama-core/src/matcher under a file called ext.rs or so. Which will have to impl Matcher.

This way you could achieve for example that in case someone would have the following kind of setup:

struct MyMarker;

ExtensionMatcher::constant(MyMarker);
// this will match in case `(*Context<S>)::get::<MyMarker>().map(|v| v == c).unwrap_or_default()`

// You can however also create it with a callback, e.g.
ExtensionMatcher::fn(|marker: &MyMarker| true)

// both the `fn` and `const` case need to be supported by `ExtensionMatcher`
// one way to achieve that is by having `ExtensionMatcher` contain a generic value `T`
// which you combine with the fact that you provide psuedo types, e.g. `struct Fn<F>(F)` and `Const<T>(T)`,
// with the types that remain private, and so that you can provide 2 implementations for `ExtensionMatcher`,
// one of `ExtensionMatcher<Fn<F>>` and one for `ExtensionMatcher<Const<T>>`. Bit of
// a hack but it works

Hopefully this gets the idea across.

calebbourg commented 4 weeks ago

@GlenDC Thank you very much for the direction. I opened a PR that I would be very grateful for feedback on at your convenience https://github.com/plabayo/rama/pull/346

The tests I have written do not pass. I'm not 100% that I am understanding the concepts involved correctly and how these functions are meant to be used but I thought this would serve as a good place to start.

GlenDC commented 3 weeks ago

I left my feedback for you in the PR @calebbourg. You were pretty close though!

GlenDC commented 3 weeks ago

Closed by #346 by @calebbourg. Thanks and congratulations with your first Rama contribution! 🎉👏

calebbourg commented 3 weeks ago

@GlenDC Thank you very much! I'd love to make another contribution. I've looked through the other issue but thought perhaps there may be one or more that you might recommend that would provide value to the project?

GlenDC commented 3 weeks ago

There are currently not some easy ones that i have just laying around, most of them will require some thinkering, for which I have no time, but if you want to dive into them they are available and I'm still available as mentor. Only downside is that they are not as clear-cut like an issue that you just solved. I cannot give exact step-by-step instructions as those are still to be figured out.

The only one that I can think of that you might be able to tackle is https://github.com/plabayo/rama/issues/330. In essence the issue should be simple. As you can easily imagine to provide a trait implementation which accepts missing auth info as anomymous. However... problem is that currently due to my fault I highly coupled that authority trait (https://ramaproxy.org/docs/rama/net/user/auth/trait.Authority.html) to https://ramaproxy.org/docs/rama/http/headers/authorization/trait.Credentials.html. So first step would be to decouple that. Meaning authorization trait has nothing to do with credentials, but we can still support that in implementations of the trait for given cases. This way it becomes easier to do step 2 which is to actually implement a AnomyousAuth struct impl of that trait. And perhaps we can add a variant Anonymous to UserId (https://ramaproxy.org/docs/rama/net/user/enum.UserId.html) so that that impl can inject UserID::Anonymous into the Context.

So instructions and idea is clear enough, but it's also plenty of work that requires some thinking (e.g. how to decouple exactly in step 1). Happy to provide guidance and feedback on any work you do and answer questions though. So the mentoring part is certainly available in https://github.com/plabayo/rama/issues/330 (say there btw if you indeed want to pick it up). But I also would not hold it against you if you think that's a step too much and you rather wait until there's some other easier task that comes up. Ones 0.2 is finished I probably have some more inspiration for smaller tasks that can be useful.

GlenDC commented 3 weeks ago

Another idea @calebbourg can be to use Rama or read more through the code and notice things that can use contributions:

Given that these are not yet clearly defined (as you would be the one finding them), might be best to first discuss them over either Email (glen@plabayo.tech) or Discord (see README), as it might be not something that is desired to be done or might require some quick discussion. If you are more certain of whatever it is that you found it can also be immediately as an issue, so a bit up to you how you handle those things.

Either way thank you once again for your contribution and for your further interest in Rama :)

calebbourg commented 3 weeks ago

Ok great thank you so very much!