traefik/integration/headers_test.go

248 lines
6.8 KiB
Go
Raw Normal View History

2019-04-02 08:40:04 +00:00
package integration
import (
"net"
2019-04-02 08:40:04 +00:00
"net/http"
"net/http/httptest"
"os"
2019-04-02 08:40:04 +00:00
"time"
"github.com/go-check/check"
2023-02-03 14:24:05 +00:00
"github.com/traefik/traefik/v3/integration/try"
2019-04-02 08:40:04 +00:00
checker "github.com/vdemeester/shakers"
)
2020-05-11 10:06:07 +00:00
// Headers tests suite.
2019-04-02 08:40:04 +00:00
type HeadersSuite struct{ BaseSuite }
func (s *HeadersSuite) TestSimpleConfiguration(c *check.C) {
cmd, display := s.traefikCmd(withConfigFile("fixtures/headers/basic.toml"))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
2020-10-09 07:32:03 +00:00
defer s.killCmd(cmd)
2019-04-02 08:40:04 +00:00
// Expected a 404 as we did not configure anything
err = try.GetRequest("http://127.0.0.1:8000/", 1000*time.Millisecond, try.StatusCodeIs(http.StatusNotFound))
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)
}
2019-04-02 08:40:04 +00:00
func (s *HeadersSuite) TestCorsResponses(c *check.C) {
file := s.adaptFile(c, "fixtures/headers/cors.toml", struct{}{})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
2019-04-02 08:40:04 +00:00
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
2020-10-09 07:32:03 +00:00
defer s.killCmd(cmd)
2019-04-02 08:40:04 +00:00
backend := startTestServer("9000", http.StatusOK, "")
2019-07-12 09:46:04 +00:00
defer backend.Close()
err = try.GetRequest(backend.URL, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
2019-04-02 08:40:04 +00:00
testCase := []struct {
desc string
requestHeaders http.Header
expected http.Header
2019-07-12 09:46:04 +00:00
reqHost string
method string
2019-04-02 08:40:04 +00:00
}{
{
desc: "simple access control allow origin",
requestHeaders: http.Header{
"Origin": {"https://foo.bar.org"},
},
expected: http.Header{
"Access-Control-Allow-Origin": {"https://foo.bar.org"},
"Vary": {"Origin"},
},
2019-07-12 09:46:04 +00:00
reqHost: "test.localhost",
method: http.MethodGet,
2019-04-02 08:40:04 +00:00
},
{
desc: "simple preflight request",
requestHeaders: http.Header{
"Access-Control-Request-Headers": {"origin"},
"Access-Control-Request-Method": {"GET", "OPTIONS"},
"Origin": {"https://foo.bar.org"},
},
expected: http.Header{
"Access-Control-Allow-Origin": {"https://foo.bar.org"},
"Access-Control-Max-Age": {"100"},
"Access-Control-Allow-Methods": {"GET,OPTIONS,PUT"},
},
2019-07-12 09:46:04 +00:00
reqHost: "test.localhost",
method: http.MethodOptions,
},
{
desc: "preflight Options request with no cors configured",
requestHeaders: http.Header{
"Access-Control-Request-Headers": {"origin"},
"Access-Control-Request-Method": {"GET", "OPTIONS"},
"Origin": {"https://foo.bar.org"},
},
expected: http.Header{
"X-Custom-Response-Header": {"True"},
},
reqHost: "test2.localhost",
method: http.MethodOptions,
},
{
desc: "preflight Get request with no cors configured",
requestHeaders: http.Header{
"Access-Control-Request-Headers": {"origin"},
"Access-Control-Request-Method": {"GET", "OPTIONS"},
"Origin": {"https://foo.bar.org"},
},
expected: http.Header{
"X-Custom-Response-Header": {"True"},
},
reqHost: "test2.localhost",
method: http.MethodGet,
2019-04-02 08:40:04 +00:00
},
}
for _, test := range testCase {
2019-07-12 09:46:04 +00:00
req, err := http.NewRequest(test.method, "http://127.0.0.1:8000/", nil)
2019-04-02 08:40:04 +00:00
c.Assert(err, checker.IsNil)
2019-07-12 09:46:04 +00:00
req.Host = test.reqHost
2019-04-02 08:40:04 +00:00
req.Header = test.requestHeaders
2019-07-12 09:46:04 +00:00
err = try.Request(req, 500*time.Millisecond, try.HasHeaderStruct(test.expected))
2019-04-02 08:40:04 +00:00
c.Assert(err, checker.IsNil)
}
}
2019-07-29 14:12:05 +00:00
func (s *HeadersSuite) TestSecureHeadersResponses(c *check.C) {
file := s.adaptFile(c, "fixtures/headers/secure.toml", struct{}{})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
2020-10-09 07:32:03 +00:00
defer s.killCmd(cmd)
2019-07-29 14:12:05 +00:00
backend := startTestServer("9000", http.StatusOK, "")
2019-07-29 14:12:05 +00:00
defer backend.Close()
err = try.GetRequest(backend.URL, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
testCase := []struct {
desc string
expected http.Header
reqHost string
internalReqHost string
2019-07-29 14:12:05 +00:00
}{
{
desc: "Permissions-Policy Set",
2019-07-29 14:12:05 +00:00
expected: http.Header{
"Permissions-Policy": {"microphone=(),"},
2019-07-29 14:12:05 +00:00
},
reqHost: "test.localhost",
internalReqHost: "internal.localhost",
2019-07-29 14:12:05 +00:00
},
}
for _, test := range testCase {
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
c.Assert(err, checker.IsNil)
req.Host = test.reqHost
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.HasHeaderStruct(test.expected))
c.Assert(err, checker.IsNil)
req, err = http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/api/rawdata", nil)
c.Assert(err, checker.IsNil)
req.Host = test.internalReqHost
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.HasHeaderStruct(test.expected))
2019-07-29 14:12:05 +00:00
c.Assert(err, checker.IsNil)
}
}
func (s *HeadersSuite) TestMultipleSecureHeadersResponses(c *check.C) {
file := s.adaptFile(c, "fixtures/headers/secure_multiple.toml", struct{}{})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
2020-10-09 07:32:03 +00:00
defer s.killCmd(cmd)
2020-07-22 12:39:45 +00:00
backend := startTestServer("9000", http.StatusOK, "")
defer backend.Close()
err = try.GetRequest(backend.URL, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
testCase := []struct {
desc string
expected http.Header
reqHost string
}{
{
desc: "Multiple Secure Headers Set",
expected: http.Header{
"X-Frame-Options": {"DENY"},
"X-Content-Type-Options": {"nosniff"},
},
reqHost: "test.localhost",
},
}
for _, test := range testCase {
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
c.Assert(err, checker.IsNil)
req.Host = test.reqHost
err = try.Request(req, 500*time.Millisecond, try.HasHeaderStruct(test.expected))
c.Assert(err, checker.IsNil)
}
}