diff --git a/cmd/api-router.go b/cmd/api-router.go index 0d23050a2..409532598 100644 --- a/cmd/api-router.go +++ b/cmd/api-router.go @@ -322,7 +322,7 @@ func corsHandler(handler http.Handler) http.Handler { xhttp.ContentEncoding, xhttp.ContentLength, xhttp.ContentType, - xhttp.ContentEncoding, + xhttp.ContentDisposition, xhttp.LastModified, xhttp.ContentLanguage, xhttp.CacheControl, diff --git a/cmd/handler-utils.go b/cmd/handler-utils.go index 24241a098..228353344 100644 --- a/cmd/handler-utils.go +++ b/cmd/handler-utils.go @@ -413,6 +413,9 @@ func extractAPIVersion(r *http.Request) string { // If none of the http routes match respond with appropriate errors func errorResponseHandler(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodOptions { + return + } version := extractAPIVersion(r) switch { case strings.HasPrefix(r.URL.Path, peerRESTPrefix): diff --git a/cmd/server_test.go b/cmd/server_test.go index 0507a1f08..8162a8e7a 100644 --- a/cmd/server_test.go +++ b/cmd/server_test.go @@ -32,6 +32,7 @@ import ( "time" humanize "github.com/dustin/go-humanize" + "github.com/minio/minio-go/v7/pkg/set" xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/pkg/bucket/policy" ) @@ -73,6 +74,7 @@ func verifyError(c *check, response *http.Response, code, description string, st func runAllTests(suite *TestSuiteCommon, c *check) { suite.SetUpSuite(c) + suite.TestCors(c) suite.TestObjectDir(c) suite.TestBucketPolicy(c) suite.TestDeleteBucket(c) @@ -187,6 +189,54 @@ func (s *TestSuiteCommon) TestBucketSQSNotificationWebHook(c *check) { verifyError(c, response, "InvalidArgument", "A specified destination ARN does not exist or is not well-formed. Verify the destination ARN.", http.StatusBadRequest) } +func (s *TestSuiteCommon) TestCors(c *check) { + expectedMap := http.Header{} + expectedMap.Add("Access-Control-Allow-Credentials", "true") + expectedMap.Add("Access-Control-Allow-Origin", "http://foobar.com") + expectedMap["Access-Control-Expose-Headers"] = []string{ + "Date", + "Etag", + "Server", + "Connection", + "Accept-Ranges", + "Content-Range", + "Content-Encoding", + "Content-Length", + "Content-Type", + "Content-Disposition", + "Last-Modified", + "Content-Language", + "Cache-Control", + "Retry-After", + "X-Amz-Bucket-Region", + "Expires", + "X-Amz*", + "X-Amz*", + "*", + } + expectedMap.Add("Vary", "Origin") + + req, _ := http.NewRequest(http.MethodOptions, s.endPoint, nil) + req.Header.Add("Origin", "http://foobar.com") + res, err := s.client.Do(req) + if err != nil { + c.Fatal(err) + } + + for k := range expectedMap { + if v, ok := res.Header[k]; !ok { + c.Errorf("Expected key %s missing from %v", k, res.Header) + } else { + expectedSet := set.CreateStringSet(expectedMap[k]...) + gotSet := set.CreateStringSet(strings.Split(v[0], ", ")...) + if !expectedSet.Equals(gotSet) { + c.Errorf("Expected value %v, got %v", strings.Join(expectedMap[k], ", "), v) + } + } + } + +} + func (s *TestSuiteCommon) TestObjectDir(c *check) { bucketName := getRandomBucketName() // HTTP request to create the bucket. diff --git a/cmd/test-utils_test.go b/cmd/test-utils_test.go index 4d6454f17..09d97711e 100644 --- a/cmd/test-utils_test.go +++ b/cmd/test-utils_test.go @@ -327,7 +327,7 @@ func UnstartedTestServer(t TestErrHandler, instanceType string) TestServer { } // Run TestServer. - testServer.Server = httptest.NewUnstartedServer(httpHandler) + testServer.Server = httptest.NewUnstartedServer(criticalErrorHandler{corsHandler(httpHandler)}) globalObjLayerMutex.Lock() globalObjectAPI = objLayer