gin
gin copied to clipboard
Draft: add X-Forwarded-Proto support
This PR is a draft, it's objective is to add a new function that is used to obtain the scheme from remote user's request. I'm not sure if this proposal will be accept by yours, so I haven't added tests and document until we can confirm it.
As you know, many servers are run behind a proxy server, that's why Gin has the mechanism like c.ClientIP() that is used to get client address from HTTP header.
In addition to the IP address, server's HTTPS certification is always configured in the proxy server too, such as Nginx, Caddy, Cloudflare. Caddy and Cloudflare are both use X-Forwarded-Proto to told the web app if the client user visit them by https or not.
Other web framework like Django also have a setting that is able to allow a trusted scheme header.
Currently Gin doesn't have a trusted method to get X-Forwarded-Proto like X-Forwarded-For. Be similar to X-Forwarded-For, we have to check if the remote ip is a trusted proxy server before getting the header. So I create this PR to implement it.
Referring to the ClientIP function, the new ClientProto function will like that:
func (c *Context) ClientProto() string {
var isTls = c.Request.TLS != nil
remoteIP := net.ParseIP(c.RemoteIP())
if remoteIP == nil {
return ""
}
trusted := c.engine.isTrustedProxy(remoteIP)
if trusted && c.engine.ForwardedByClientProto && c.engine.RemoteProtoHeaders != nil {
for _, headerName := range c.engine.RemoteProtoHeaders {
proto, valid := c.engine.validateHeader(c.requestHeader(headerName))
if valid {
return proto
}
}
}
if isTls {
return "https"
} else {
return "http"
}
}
Looking forward your reply, we can discuss about it.
Another idea is to add a new function c.FromTrustedProxy() to gin.Context. Developers can use this function to check if the request is from a trusted proxy server, then write their own code to get any HTTP header safely.
See https://github.com/gin-gonic/gin/pull/3448