middleware proxy pass origin Host header
Issue Description
Requests that reach the final server contain the Host header from the original request. If the destination server checks the header Host (eg: ingress in k8s cluster with Host rules) and if the values ​​do not match, then the request is rejected or etc...
Checklist
- [x] Dependencies installed
- [x] No typos
- [x] Searched existing issues and docs
Expected behaviour
proxy replace request.Host to target.URL.Host
Actual behaviour
request.Host stay immutable
Steps to reproduce
- http server which checks
Hostheader (srv1) - http server with echo using middleware proxy (proxy) - target url to srv1, domain for proxy <> domain for srv1
- run both srv1 and proxy
- request to proxy
client (localhost) --(Host: proxy.domain.com)--> proxy (proxy.domain.com) --(Host: proxy.domain.com)--> srv1 (srv1.domain.com)
Version/commit
echo v4.12.0
dirty workaround
- use vendoring
- add to github.com/labstack/echo/v4/middleware/proxy.go
req.Host = tgt.URL.Host
P.S. Maybe add option to ProxyConfig
You can do this right now by adding a custom Transport.
Here is an example where I had to Reverse Proxy for minio presigned urls to work when minio is running in k8s.
type customRoundTripper struct {
Host string
}
func (c *customRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
r.Host = c.Host
return http.DefaultTransport.RoundTrip(r)
}
func setupHttp() {
url1, err := url.Parse("http://minio-s3:9000")
if err != nil {
log.Fatal().Err(err).Msg("failed to parse url")
}
targets := []*middleware.ProxyTarget{
{
URL: url1,
},
}
// We need to change the host by using a custom http.RoundTripper
// Use a group to proxy path /minio
g := echo.Group("/minio")
g.Use(middleware.ProxyWithConfig(middleware.ProxyConfig{
Balancer: middleware.NewRoundRobinBalancer(targets),
// Strip out the /minio
Rewrite: map[string]string{"/minio/*": "/$1"},
Transport: &customRoundTripper{s.logger, s.cfg.S3.URL},
}))
}
@steffkelsey Thanks for this! I had a much more complex solution in place, this is exactly what's required 😆