http servers: allow CORS to be set with --allow-origin flag - fixes #5078

Some changes about test cases:
Because MiddlewareCORS will return early on OPTIONS request,
this middleware should only be used once at NewServer function.
Test cases should pass AllowOrigin config instead of adding
this middleware again.

A new test case was added to test CORS preflight request with
an authenticator. Preflight request should always return 200 OK
regardless of autentications.

Co-authored-by: yuudi <yuudi@users.noreply.github.com>
This commit is contained in:
yuudi
2023-07-26 05:15:54 -04:00
committed by GitHub
parent 3ed4a2e963
commit 6c8148ef39
8 changed files with 95 additions and 75 deletions

View File

@@ -329,23 +329,22 @@ var _testCORSHeaderKeys = []string{
func TestMiddlewareCORS(t *testing.T) {
servers := []struct {
name string
http Config
origin string
name string
http Config
}{
{
name: "EmptyOrigin",
http: Config{
ListenAddr: []string{"127.0.0.1:0"},
ListenAddr: []string{"127.0.0.1:0"},
AllowOrigin: "",
},
origin: "",
},
{
name: "CustomOrigin",
http: Config{
ListenAddr: []string{"127.0.0.1:0"},
ListenAddr: []string{"127.0.0.1:0"},
AllowOrigin: "http://test.rclone.org",
},
origin: "http://test.rclone.org",
},
}
@@ -357,8 +356,6 @@ func TestMiddlewareCORS(t *testing.T) {
require.NoError(t, s.Shutdown())
}()
s.Router().Use(MiddlewareCORS(ss.origin))
expected := []byte("data")
s.Router().Mount("/", testEchoHandler(expected))
s.Serve()
@@ -384,8 +381,69 @@ func TestMiddlewareCORS(t *testing.T) {
}
expectedOrigin := url
if ss.origin != "" {
expectedOrigin = ss.origin
if ss.http.AllowOrigin != "" {
expectedOrigin = ss.http.AllowOrigin
}
require.Equal(t, expectedOrigin, resp.Header.Get("Access-Control-Allow-Origin"), "allow origin should match")
})
}
}
func TestMiddlewareCORSWithAuth(t *testing.T) {
authServers := []struct {
name string
http Config
auth AuthConfig
}{
{
name: "ServerWithAuth",
http: Config{
ListenAddr: []string{"127.0.0.1:0"},
AllowOrigin: "http://test.rclone.org",
},
auth: AuthConfig{
Realm: "test",
BasicUser: "test_user",
BasicPass: "test_pass",
},
},
}
for _, ss := range authServers {
t.Run(ss.name, func(t *testing.T) {
s, err := NewServer(context.Background(), WithConfig(ss.http))
require.NoError(t, err)
defer func() {
require.NoError(t, s.Shutdown())
}()
expected := []byte("data")
s.Router().Mount("/", testEchoHandler(expected))
s.Serve()
url := testGetServerURL(t, s)
client := &http.Client{}
req, err := http.NewRequest("OPTIONS", url, nil)
require.NoError(t, err)
resp, err := client.Do(req)
require.NoError(t, err)
defer func() {
_ = resp.Body.Close()
}()
require.Equal(t, http.StatusOK, resp.StatusCode, "OPTIONS should return ok even if not authenticated")
testExpectRespBody(t, resp, []byte{})
for _, key := range _testCORSHeaderKeys {
require.Contains(t, resp.Header, key, "CORS headers should be sent even if not authenticated")
}
expectedOrigin := url
if ss.http.AllowOrigin != "" {
expectedOrigin = ss.http.AllowOrigin
}
require.Equal(t, expectedOrigin, resp.Header.Get("Access-Control-Allow-Origin"), "allow origin should match")
})