http-rs / surf

Fast and friendly HTTP client framework for async Rust
https://docs.rs/surf
Apache License 2.0
1.47k stars 120 forks source link

how to use proxy #114

Open CGQAQ opened 4 years ago

CGQAQ commented 4 years ago

The reqwest library support proxy very well. I am wondering surf can use proxy or not, because I want use async-std instead of tokio which reqwest depends on

yoshuawuyts commented 4 years ago

@CGQAQ there's nothing inherent in Surf that would stop you from using it as a proxy. All that's needed is pass an incoming stream as surf's request body. And pass Surf's resposne stream as the server's response body.

We want to make this real easy to do with Tide + Surf, but haven't quite gotten around to that unfortunately. The general idea should already be possible though!

CGQAQ commented 4 years ago

@yoshuawuyts No, I didn't mean use it as proxy, I mean request through some proxy, in my country have censorship, it is really important

yoshuawuyts commented 4 years ago

@CGQAQ oh, like SOCK5. Unfortunately I know very little about that, so if you have any pointers what we could do here to help with that I'd love to know more.

CGQAQ commented 4 years ago

@yoshuawuyts just like these Proxy, support http/https/socks proxy And HTTP_PROXY, HTTPS_PROXY, SOCKS_PROXY and NO_PROXY system variables support

oleid commented 4 years ago

Proxy support might be quite handy ; I frequently use socks proxy at work, which are created via ssh's DynamicForwarding (-D) option.

yoshuawuyts commented 4 years ago

Having a design on how we would integrate proxy support would be fantastic too. I imagine it probably wouldn't work in the browser (so no WASM support), and perhaps some client backends already ship support for it out of the box.

If anyone has more details on how this works it'd be very helpful. We could dig through reqwests's source to look at how they've implemented it, but having an explainer (or pointer to one) would be much appreciated! E.g. do we intercept TCP requests and forward them through an SSH connection? How does this work?

oleid commented 4 years ago

From what I understand (and my understanding is quite rudimentary, so please take this with a grain of salt) , it works as follows :

The client wants to talk to server S via Proxy P. So client opens a tcp connection to P, where it talks about it's intentions via a socks protocol. (greeting, maybe authentication, the desired destination S). If this all got ACKed, all further traffic to P is automatically forwarded to S.

If this is correct, socks support would only affect the connection phase. I guess that makes the integration less invasive.

EDIT: Fixed typo

EDIT2: Socks is not related to ssh. Only openssh happens to provide socks server support.

kgv commented 4 years ago

@yoshuawuyts Good examples from @alexcrichton for understanding how proxy work (server/client): 1) uses mio socks5-rs 2) uses tokio tokio-socks5

they are very simple and contain only targeted implementation.

And some descriptions: rfc wiki

vkill commented 4 years ago

@CGQAQ please try use async-h1

vkill commented 4 years ago

This feature needs to reuse stream, but HttpClient trait don't support it.

Maybe need change HttpClient trait like the following

pub trait HttpClient: std::fmt::Debug + Unpin + Send + Sync + Clone + 'static {
    type Error: Send + Sync + Into<Error>;

    fn create_stream(req: Request) -> BoxFuture<'static, Result<Stream, Self::Error>>;

    fn send(&self, req: Request, stream: Stream) -> BoxFuture<'static, Result<Response, Self::Error>>;
}

pub type Stream = Foo;
xiuno commented 3 years ago

official has the milestone to support to request https by proxy ?