omjadas / hudsucker

Intercepting HTTP/S proxy
https://crates.io/crates/hudsucker
Apache License 2.0
209 stars 37 forks source link

[Feature Request] Upstream Proxy #51

Open roniemartinez opened 1 year ago

roniemartinez commented 1 year ago

I noticed that this crate supports upstream proxy before in https://github.com/omjadas/hudsucker/commit/b7a213615d12df82ca9631626c91aa426709600b

But it was removed in https://github.com/omjadas/hudsucker/commit/408999b5d9a9dce2cbbf9d60cfb2e92feed806ef

This is a very useful feature and might be worth it to bring it back?

I would like to propose a more flexible design instead of the original implementation by adding this to HttpHandler which will give an option to route traffic based on request or rotate from a list of upstream proxies

pub trait HttpHandler: Clone + Send + Sync + 'static {

    async fn get_upstream_proxy(&mut self, _ctx: &HttpContext, _req: &Request<Body>) -> String {
       // return upstream URL string here
    }
}
omjadas commented 1 year ago

The reason that I removed the initial upstream proxy implementation was because it did not work for websockets. If I can figure out a way that works for both HTTP and websockets, then I would be happy to include it as an implementation. I do like the idea of integrating the upstream proxy config with the HttpHandler.

roniemartinez commented 1 year ago

This blog could be of interest as a reference since Hudsucker already uses tungstenite.

We could start with normal HTTP proxy support w/o websockets and make it optional with a flag similar to should_intercept.

maxmindlin commented 9 months ago

+1 on the upstream proxy being useful for normal HTTP requests. I was going to implement this on my own (now with that git commit as reference), is there any other reference code or workaround thats useful in the meantime?

roniemartinez commented 9 months ago

Going back to the open Tungstenite issue, there seems to be another attempt in https://github.com/snapview/tungstenite-rs/issues/406#issuecomment-1924106098 earlier.

maxmindlin commented 9 months ago

Thanks @roniemartinez , looking at the previous code for the http proxy I see they were using hyper-proxy. Thats also what I was attempting to use but it seems like it might not be actively maintained anymore. Do you know if its still the best way forward for an http upstream proxy?

roniemartinez commented 9 months ago

Not sure about other libraries, but currently hyper-proxy (HTTP) and hyper-socks2 (SOCKS) are the only libraries that work.

timercrack commented 5 months ago

The reason that I removed the initial upstream proxy implementation was because it did not work for websockets. If I can figure out a way that works for both HTTP and websockets, then I would be happy to include it as an implementation. I do like the idea of integrating the upstream proxy config with the HttpHandler.

Do you have a solution now? Like mitmproxy python implementation?

omjadas commented 5 months ago

Do you have a solution now? Like mitmproxy python implementation?

There isn't support built directly into this library, however, you can either provide a custom hyper client (potentially using hyper-proxy2) or forward the requests yourself in the handle_request method.

timercrack commented 5 months ago

Could you provide an example? How to forward https and ws to additional target in handle_request?

futurist commented 4 months ago

+1 for this feature, I've used the goproxy version to change upstream Scheme and URL as below:

https://github.com/futurist/goproxy/blob/3d0e880f60f54fc9775741c2eacb16290c8cda6b/examples/goproxy-customca/main.go#L19