Allow X-Forwarded-For delete operation
Co-authored-by: landrybe <lbenguigui@gmail.com>
This commit is contained in:
parent
dbc679dc30
commit
4d63eb30f9
4 changed files with 82 additions and 1 deletions
|
@ -0,0 +1,31 @@
|
||||||
|
[global]
|
||||||
|
checkNewVersion = false
|
||||||
|
sendAnonymousUsage = false
|
||||||
|
|
||||||
|
[log]
|
||||||
|
level = "DEBUG"
|
||||||
|
|
||||||
|
[entryPoints]
|
||||||
|
[entryPoints.web]
|
||||||
|
address = ":8000"
|
||||||
|
|
||||||
|
[providers.file]
|
||||||
|
filename = "{{ .SelfFilename }}"
|
||||||
|
|
||||||
|
## dynamic configuration ##
|
||||||
|
|
||||||
|
[http.routers]
|
||||||
|
[http.routers.router1]
|
||||||
|
rule = "Host(`test.localhost`)"
|
||||||
|
middlewares = ["remove"]
|
||||||
|
service = "service1"
|
||||||
|
|
||||||
|
[http.middlewares]
|
||||||
|
[http.middlewares.remove.headers.customRequestHeaders]
|
||||||
|
X-Forwarded-For = ""
|
||||||
|
Foo = ""
|
||||||
|
|
||||||
|
[http.services]
|
||||||
|
[http.services.service1.loadBalancer]
|
||||||
|
[[http.services.service1.loadBalancer.servers]]
|
||||||
|
url = "http://127.0.0.1:9000"
|
|
@ -1,7 +1,9 @@
|
||||||
package integration
|
package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -25,6 +27,46 @@ func (s *HeadersSuite) TestSimpleConfiguration(c *check.C) {
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *HeadersSuite) TestReverseProxyHeaderRemoved(c *check.C) {
|
||||||
|
file := s.adaptFile(c, "fixtures/headers/remove_reverseproxy_headers.toml", struct{}{})
|
||||||
|
defer os.Remove(file)
|
||||||
|
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||||
|
defer display(c)
|
||||||
|
|
||||||
|
err := cmd.Start()
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
defer s.killCmd(cmd)
|
||||||
|
|
||||||
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
_, found := r.Header["X-Forwarded-Host"]
|
||||||
|
c.Assert(found, checker.True)
|
||||||
|
_, found = r.Header["Foo"]
|
||||||
|
c.Assert(found, checker.False)
|
||||||
|
_, found = r.Header["X-Forwarded-For"]
|
||||||
|
c.Assert(found, checker.False)
|
||||||
|
})
|
||||||
|
|
||||||
|
listener, err := net.Listen("tcp", "127.0.0.1:9000")
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
|
ts := &httptest.Server{
|
||||||
|
Listener: listener,
|
||||||
|
Config: &http.Server{Handler: handler},
|
||||||
|
}
|
||||||
|
ts.Start()
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
req.Host = "test.localhost"
|
||||||
|
req.Header = http.Header{
|
||||||
|
"Foo": {"bar"},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
|
||||||
|
c.Assert(err, checker.IsNil)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *HeadersSuite) TestCorsResponses(c *check.C) {
|
func (s *HeadersSuite) TestCorsResponses(c *check.C) {
|
||||||
file := s.adaptFile(c, "fixtures/headers/cors.toml", struct{}{})
|
file := s.adaptFile(c, "fixtures/headers/cors.toml", struct{}{})
|
||||||
defer os.Remove(file)
|
defer os.Remove(file)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
|
|
||||||
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||||
"github.com/traefik/traefik/v2/pkg/log"
|
"github.com/traefik/traefik/v2/pkg/log"
|
||||||
|
"github.com/vulcand/oxy/v2/forward"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Header is a middleware that helps setup a few basic security features.
|
// Header is a middleware that helps setup a few basic security features.
|
||||||
|
@ -70,6 +71,10 @@ func (s *Header) modifyCustomRequestHeaders(req *http.Request) {
|
||||||
// Loop through Custom request headers
|
// Loop through Custom request headers
|
||||||
for header, value := range s.headers.CustomRequestHeaders {
|
for header, value := range s.headers.CustomRequestHeaders {
|
||||||
switch {
|
switch {
|
||||||
|
// Handling https://github.com/golang/go/commit/ecdbffd4ec68b509998792f120868fec319de59b.
|
||||||
|
case value == "" && header == forward.XForwardedFor:
|
||||||
|
req.Header[header] = nil
|
||||||
|
|
||||||
case value == "":
|
case value == "":
|
||||||
req.Header.Del(header)
|
req.Header.Del(header)
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,14 @@ func TestNewHeader_customRequestHeader(t *testing.T) {
|
||||||
desc: "delete a header",
|
desc: "delete a header",
|
||||||
cfg: dynamic.Headers{
|
cfg: dynamic.Headers{
|
||||||
CustomRequestHeaders: map[string]string{
|
CustomRequestHeaders: map[string]string{
|
||||||
|
"X-Forwarded-For": "",
|
||||||
"X-Custom-Request-Header": "",
|
"X-Custom-Request-Header": "",
|
||||||
"Foo": "",
|
"Foo": "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: http.Header{},
|
expected: http.Header{
|
||||||
|
"X-Forwarded-For": nil,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "override a header",
|
desc: "override a header",
|
||||||
|
|
Loading…
Reference in a new issue