danielSanchezQ / warp-reverse-proxy

Fully composable warp filter that can be used as a reverse proxy.
https://github.com/danielSanchezQ/warp-reverse-proxy
MIT License
48 stars 18 forks source link

Feature request : websocket support (and altering of host header) #49

Open nicolaspernoud opened 2 years ago

nicolaspernoud commented 2 years ago

Hello,

Thanks for this useful work.

It would be nice if this reverse proxy allowed proxying of websockets, as Go proxy does.

I tried proxying "websocketstest.com" through this proxy and it does not work.

Also, to do this proxying (as well with www.example.com), I needed to alter the host header to match the host of the proxy target in the filtered_data_to_request function. It could be nice if it was done by default, to allow proxying servers with virtual hosts.

Thanks and best regards.

PS : the (dirty) way I replaced the host header below :


    let host = proxy_address
        .replace("https://", "")
        .replace("http://", "")
        .replace("/", "");

    let proxy_uri = if let Some(params) = params {
        format!("{}?{}", proxy_address, params)
    } else {
        proxy_address
    };

    let mut headers = remove_hop_headers(&headers);
    headers.insert("host", host.parse().unwrap());
danielSanchezQ commented 2 years ago

Hi @nicolaspernoud !

Thanks for the idea. I think this may be pretty useful. But I may be missing things. I don't know exactly how to forward the ws connection. Since you would have to keep both connections alive, and the filter is not ready for that. I would have to investigate it.

Regarding the headers: your example looks pretty much of what it should.

I will take a deeper look once I have the time for it. PRs are welcome if you want to go ahead and try to make some code example 😃

nicolaspernoud commented 2 years ago

Hello,

Regarding the web sockets, golang proxy seems to be able to hijack the TCP connection when a upgrade header is present, writing only the headers with http handler and getting the body from an opaque tcp stream (?). The hard(est) part would be to come with something to hijack the connection I guess... (https://golang.org/src/net/http/httputil/reverseproxy.go)

Regarding the headers, I can surely do a pull request but the way I did it seems unclean, I'll see if I can come with something better. If so, I'll do a pull request.

Thanks and best regards.

danielSanchezQ commented 2 years ago

Awesome, I'll take a look at the go code (it was a reference for this implementation actually). Thanks!

vidhatha commented 1 year ago

@danielSanchezQ This would be a really useful feature to prioritize!

danielSanchezQ commented 1 year ago

@vidhatha Sadly I think I lack the knowledge and the time to implement it myself atm. But PRs, documentation and help in general is more than welcome.

vidhatha commented 1 year ago

@vidhatha Sadly I think I lack the knowledge and the time to implement it myself atm. But PRs, documentation and help in general is more than welcome.

@danielSanchezQ Thanks for the quick response! completely understand. Right now I think what @nicolaspernoud suggested seems a good workaround. Let me see if I can help with this.

Thanks for you all your efforts btw.