diff --git a/pkg/genericapiserver/config.go b/pkg/genericapiserver/config.go index d73fe21fad1..88b5ff7ef80 100644 --- a/pkg/genericapiserver/config.go +++ b/pkg/genericapiserver/config.go @@ -353,7 +353,7 @@ func (c Config) New() (*GenericAPIServer, error) { func (s *GenericAPIServer) buildHandlerChains(c *Config, handler http.Handler) (secure http.Handler, insecure http.Handler) { // filters which insecure and secure have in common - handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, "true") + handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true") // insecure filters insecure = handler diff --git a/pkg/genericapiserver/filters/cors.go b/pkg/genericapiserver/filters/cors.go index ac904e221d0..c463047879e 100644 --- a/pkg/genericapiserver/filters/cors.go +++ b/pkg/genericapiserver/filters/cors.go @@ -35,7 +35,7 @@ import ( // WithCORS is a simple CORS implementation that wraps an http Handler. // Pass nil for allowedMethods and allowedHeaders to use the defaults. If allowedOriginPatterns // is empty or nil, no CORS support is installed. -func WithCORS(handler http.Handler, allowedOriginPatterns []string, allowedMethods []string, allowedHeaders []string, allowCredentials string) http.Handler { +func WithCORS(handler http.Handler, allowedOriginPatterns []string, allowedMethods []string, allowedHeaders []string, exposedHeaders []string, allowCredentials string) http.Handler { if len(allowedOriginPatterns) == 0 { return handler } @@ -58,8 +58,12 @@ func WithCORS(handler http.Handler, allowedOriginPatterns []string, allowedMetho if allowedHeaders == nil { allowedHeaders = []string{"Content-Type", "Content-Length", "Accept-Encoding", "X-CSRF-Token", "Authorization", "X-Requested-With", "If-Modified-Since"} } + if exposedHeaders == nil { + exposedHeaders = []string{"Date"} + } w.Header().Set("Access-Control-Allow-Methods", strings.Join(allowedMethods, ", ")) w.Header().Set("Access-Control-Allow-Headers", strings.Join(allowedHeaders, ", ")) + w.Header().Set("Access-Control-Expose-Headers", strings.Join(exposedHeaders, ", ")) w.Header().Set("Access-Control-Allow-Credentials", allowCredentials) // Stop here if its a preflight OPTIONS request diff --git a/pkg/genericapiserver/filters/cors_test.go b/pkg/genericapiserver/filters/cors_test.go index d62e83d51be..817c01a6f2c 100644 --- a/pkg/genericapiserver/filters/cors_test.go +++ b/pkg/genericapiserver/filters/cors_test.go @@ -39,7 +39,7 @@ func TestCORSAllowedOrigins(t *testing.T) { for _, item := range table { handler := WithCORS( http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}), - item.allowedOrigins, nil, nil, "true", + item.allowedOrigins, nil, nil, nil, "true", ) server := httptest.NewServer(handler) defer server.Close() @@ -72,6 +72,9 @@ func TestCORSAllowedOrigins(t *testing.T) { if response.Header.Get("Access-Control-Allow-Methods") == "" { t.Errorf("Expected Access-Control-Allow-Methods header to be set") } + if response.Header.Get("Access-Control-Expose-Headers") != "Date" { + t.Errorf("Expected Date in Access-Control-Expose-Headers header") + } } else { if response.Header.Get("Access-Control-Allow-Origin") != "" { t.Errorf("Expected Access-Control-Allow-Origin header to not be set") @@ -88,6 +91,9 @@ func TestCORSAllowedOrigins(t *testing.T) { if response.Header.Get("Access-Control-Allow-Methods") != "" { t.Errorf("Expected Access-Control-Allow-Methods header to not be set") } + if response.Header.Get("Access-Control-Expose-Headers") == "Date" { + t.Errorf("Expected Date in Access-Control-Expose-Headers header") + } } } }