Reputation: 1
I just recently started coding in go and thus I am not so skilled yet.
I have a use case where I want to implement a reverse proxy as a gin route. So my route looks like this:
server.router.POST("/console", server.proxyConsoleUrl)
And my handler function something like this:
func (server *Server) proxyConsoleUrl(ctx *gin.Context) {
director := func(req *http.Request) {
r := ctx.Request
// This is not working, scheme wss is not supported
req.URL.Scheme = "wss"
req.URL.Host = "192.168.******:8006"
// The path which gets proxied should be overriden
req.URL.RawPath = "/api2/json/nodes/something/qemu/123/vncwebsocket?port=5900&vncticket=something"
req.Header["my-header"] = []string{r.Header.Get("my-header")}
// Golang camelcases headers
delete(req.Header, "My-Header")
// This header has to be added to every request which gets proxied
req.Header["Authorization"] = []string{"MYCUSTOMHEADER"}
}
proxy := &httputil.ReverseProxy{Director: director, Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}}
proxy.ServeHTTP(ctx.Writer, ctx.Request)
}
So my first problem is, that httputil.ReverseProxy doesn't support web socket as far as I know and noticed when running my code:
httputil: unsupported protocol scheme "wss"
The Second problem is, that I want to override the backend url as well as add custom headers which are added by the proxy.
Maybe someone has an idea hot to implement this, if it's even possible. -Thanks in advance
Upvotes: 0
Views: 1741
Reputation: 120999
WebSocket support was added to httputil.ReverseProxy in Go version 1.12.
Use the result of url.Parse("https://192.168.******:8006/api2/json/nodes/something/qemu/123/vncwebsocket?port=5900&vncticket=something")
to set the target URL. This fixes the following issues:
Create the proxy once and reuse it. The important point is to create an reuse a single transport per the Transport documentation. Reusing the proxy accomplishes that goal.
func createProxy() *httputil.ReverseProxy {
target, _ := url.Parse("https://192.168.******:8006/api2/json/nodes/something/qemu/123/vncwebsocket?port=5900&vncticket=something")
director := func(req *http.Request) {
req.URL = target
req.Header["my-header"] = []string{req.Header.Get("my-header")}
delete(req.Header, "My-Header")
req.Header["Authorization"] = []string{"MYCUSTOMHEADER"}
}
return &httputil.ReverseProxy{Director: director, Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
TLSHandshakeTimeout: 10 * time.Second,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}}
}
var proxy = createProxy()
func (server *Server) proxyConsoleUrl(ctx *gin.Context) {
proxy.ServeHTTP(ctx.Writer, ctx.Request)
}
Upvotes: 1