Properly add response headers for CORS
This commit is contained in:
parent
74c5ec70a9
commit
3f6ea04048
8 changed files with 198 additions and 138 deletions
|
@ -8,18 +8,3 @@
|
|||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
|
||||
[providers]
|
||||
[providers.file]
|
||||
|
||||
## dynamic configuration ##
|
||||
|
||||
[http.routers]
|
||||
[http.routers.router1]
|
||||
rule = "Host(`test.localhost`)"
|
||||
service = "service1"
|
||||
|
||||
[http.services]
|
||||
[http.services.service1.loadBalancer]
|
||||
[[http.services.service1.loadBalancer.servers]]
|
||||
url = "http://172.17.0.2:80"
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
[http.routers]
|
||||
[http.routers.router1]
|
||||
rule = "Host(`test.localhost`)"
|
||||
middlewares = ["cors"]
|
||||
service = "service1"
|
||||
|
||||
[http.routers.router2]
|
||||
rule = "Host(`test2.localhost`)"
|
||||
middlewares = ["nocors"]
|
||||
service = "service1"
|
||||
|
||||
[http.middlewares]
|
||||
|
@ -26,7 +32,11 @@
|
|||
accessControlMaxAge = 100
|
||||
addVaryHeader = true
|
||||
|
||||
[http.middlewares.nocors.Headers]
|
||||
[http.middlewares.nocors.Headers.CustomResponseHeaders]
|
||||
X-Custom-Response-Header = "True"
|
||||
|
||||
[http.services]
|
||||
[http.services.service1.loadBalancer]
|
||||
[[http.services.service1.loadBalancer.servers]]
|
||||
url = "http://172.17.0.2:80"
|
||||
url = "http://127.0.0.1:9000"
|
||||
|
|
|
@ -12,12 +12,6 @@ import (
|
|||
// Headers test suites
|
||||
type HeadersSuite struct{ BaseSuite }
|
||||
|
||||
func (s *HeadersSuite) SetUpSuite(c *check.C) {
|
||||
s.createComposeProject(c, "headers")
|
||||
|
||||
s.composeProject.Start(c)
|
||||
}
|
||||
|
||||
func (s *HeadersSuite) TestSimpleConfiguration(c *check.C) {
|
||||
cmd, display := s.traefikCmd(withConfigFile("fixtures/headers/basic.toml"))
|
||||
defer display(c)
|
||||
|
@ -38,10 +32,18 @@ func (s *HeadersSuite) TestCorsResponses(c *check.C) {
|
|||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
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
|
||||
requestHeaders http.Header
|
||||
expected http.Header
|
||||
reqHost string
|
||||
method string
|
||||
}{
|
||||
{
|
||||
desc: "simple access control allow origin",
|
||||
|
@ -52,33 +54,9 @@ func (s *HeadersSuite) TestCorsResponses(c *check.C) {
|
|||
"Access-Control-Allow-Origin": {"https://foo.bar.org"},
|
||||
"Vary": {"Origin"},
|
||||
},
|
||||
reqHost: "test.localhost",
|
||||
method: http.MethodGet,
|
||||
},
|
||||
}
|
||||
|
||||
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.localhost"
|
||||
req.Header = test.requestHeaders
|
||||
|
||||
err = try.Request(req, 500*time.Millisecond, try.HasBody(), try.HasHeaderStruct(test.expected))
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *HeadersSuite) TestCorsPreflightResponses(c *check.C) {
|
||||
cmd, display := s.traefikCmd(withConfigFile("fixtures/headers/cors.toml"))
|
||||
defer display(c)
|
||||
|
||||
err := cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
testCase := []struct {
|
||||
desc string
|
||||
requestHeaders http.Header
|
||||
expected http.Header
|
||||
}{
|
||||
{
|
||||
desc: "simple preflight request",
|
||||
requestHeaders: http.Header{
|
||||
|
@ -91,16 +69,44 @@ func (s *HeadersSuite) TestCorsPreflightResponses(c *check.C) {
|
|||
"Access-Control-Max-Age": {"100"},
|
||||
"Access-Control-Allow-Methods": {"GET,OPTIONS,PUT"},
|
||||
},
|
||||
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,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCase {
|
||||
req, err := http.NewRequest(http.MethodOptions, "http://127.0.0.1:8000/", nil)
|
||||
req, err := http.NewRequest(test.method, "http://127.0.0.1:8000/", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
req.Host = "test.localhost"
|
||||
req.Host = test.reqHost
|
||||
req.Header = test.requestHeaders
|
||||
|
||||
err = try.Request(req, 500*time.Millisecond, try.HasBody(), try.HasHeaderStruct(test.expected))
|
||||
err = try.Request(req, 500*time.Millisecond, try.HasHeaderStruct(test.expected))
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
whoami1:
|
||||
image: containous/whoami
|
||||
ports:
|
||||
- "8881:80"
|
|
@ -168,18 +168,17 @@ func HasHeaderValue(header, value string, exactMatch bool) ResponseCondition {
|
|||
func HasHeaderStruct(header http.Header) ResponseCondition {
|
||||
return func(res *http.Response) error {
|
||||
for key := range header {
|
||||
if _, ok := res.Header[key]; ok {
|
||||
// Header exists in the response, test it.
|
||||
eq := reflect.DeepEqual(header[key], res.Header[key])
|
||||
if !eq {
|
||||
return fmt.Errorf("for header %s got values %v, wanted %v", key, res.Header[key], header[key])
|
||||
}
|
||||
if _, ok := res.Header[key]; !ok {
|
||||
return fmt.Errorf("header %s not present in the response. Expected headers: %v Got response headers: %v", key, header, res.Header)
|
||||
}
|
||||
|
||||
// Header exists in the response, test it.
|
||||
if !reflect.DeepEqual(header[key], res.Header[key]) {
|
||||
return fmt.Errorf("for header %s got values %v, wanted %v", key, res.Header[key], header[key])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// DoCondition is a retry condition function.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue