mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Merge pull request #81946 from deads2k/cache
add cache-control headers to kube-apiserver
This commit is contained in:
commit
8af33f9733
@ -17,10 +17,11 @@ limitations under the License.
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
goruntime "runtime"
|
goruntime "runtime"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
|
genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
|
||||||
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
apiserver "k8s.io/apiserver/pkg/server"
|
apiserver "k8s.io/apiserver/pkg/server"
|
||||||
@ -46,6 +47,7 @@ func BuildHandlerChain(apiHandler http.Handler, authorizationInfo *apiserver.Aut
|
|||||||
handler = genericapifilters.WithAuthentication(handler, authenticationInfo.Authenticator, failedHandler, nil)
|
handler = genericapifilters.WithAuthentication(handler, authenticationInfo.Authenticator, failedHandler, nil)
|
||||||
}
|
}
|
||||||
handler = genericapifilters.WithRequestInfo(handler, requestInfoResolver)
|
handler = genericapifilters.WithRequestInfo(handler, requestInfoResolver)
|
||||||
|
handler = genericapifilters.WithCacheControl(handler)
|
||||||
handler = genericfilters.WithPanicRecovery(handler)
|
handler = genericfilters.WithPanicRecovery(handler)
|
||||||
|
|
||||||
return handler
|
return handler
|
||||||
|
@ -287,6 +287,7 @@ func buildHandlerChain(handler http.Handler, authn authenticator.Request, authz
|
|||||||
handler = genericapifilters.WithAuthorization(handler, authz, legacyscheme.Codecs)
|
handler = genericapifilters.WithAuthorization(handler, authz, legacyscheme.Codecs)
|
||||||
handler = genericapifilters.WithAuthentication(handler, authn, failedHandler, nil)
|
handler = genericapifilters.WithAuthentication(handler, authn, failedHandler, nil)
|
||||||
handler = genericapifilters.WithRequestInfo(handler, requestInfoResolver)
|
handler = genericapifilters.WithRequestInfo(handler, requestInfoResolver)
|
||||||
|
handler = genericapifilters.WithCacheControl(handler)
|
||||||
handler = genericfilters.WithPanicRecovery(handler)
|
handler = genericfilters.WithPanicRecovery(handler)
|
||||||
|
|
||||||
return handler
|
return handler
|
||||||
|
@ -34,6 +34,7 @@ func BuildInsecureHandlerChain(apiHandler http.Handler, c *server.Config) http.H
|
|||||||
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.LongRunningFunc)
|
handler = genericfilters.WithMaxInFlightLimit(handler, c.MaxRequestsInFlight, c.MaxMutatingRequestsInFlight, c.LongRunningFunc)
|
||||||
handler = genericfilters.WithWaitGroup(handler, c.LongRunningFunc, c.HandlerChainWaitGroup)
|
handler = genericfilters.WithWaitGroup(handler, c.LongRunningFunc, c.HandlerChainWaitGroup)
|
||||||
handler = genericapifilters.WithRequestInfo(handler, server.NewRequestInfoResolver(c))
|
handler = genericapifilters.WithRequestInfo(handler, server.NewRequestInfoResolver(c))
|
||||||
|
handler = genericapifilters.WithCacheControl(handler)
|
||||||
handler = genericfilters.WithPanicRecovery(handler)
|
handler = genericfilters.WithPanicRecovery(handler)
|
||||||
|
|
||||||
return handler
|
return handler
|
||||||
|
@ -13,6 +13,7 @@ go_test(
|
|||||||
"authentication_test.go",
|
"authentication_test.go",
|
||||||
"authn_audit_test.go",
|
"authn_audit_test.go",
|
||||||
"authorization_test.go",
|
"authorization_test.go",
|
||||||
|
"cachecontrol_test.go",
|
||||||
"impersonation_test.go",
|
"impersonation_test.go",
|
||||||
"requestinfo_test.go",
|
"requestinfo_test.go",
|
||||||
],
|
],
|
||||||
@ -44,6 +45,7 @@ go_library(
|
|||||||
"authentication.go",
|
"authentication.go",
|
||||||
"authn_audit.go",
|
"authn_audit.go",
|
||||||
"authorization.go",
|
"authorization.go",
|
||||||
|
"cachecontrol.go",
|
||||||
"doc.go",
|
"doc.go",
|
||||||
"impersonation.go",
|
"impersonation.go",
|
||||||
"requestinfo.go",
|
"requestinfo.go",
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package filters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WithCacheControl sets the Cache-Control header to "no-cache, private" because all servers are protected by authn/authz.
|
||||||
|
// see https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching#defining_optimal_cache-control_policy
|
||||||
|
func WithCacheControl(handler http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
|
// Set the cache-control header if it is not already set
|
||||||
|
if _, ok := w.Header()["Cache-Control"]; !ok {
|
||||||
|
w.Header().Set("Cache-Control", "no-cache, private")
|
||||||
|
}
|
||||||
|
handler.ServeHTTP(w, req)
|
||||||
|
})
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package filters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCacheControl(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
path string
|
||||||
|
|
||||||
|
startingHeader string
|
||||||
|
expectedHeader string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "simple",
|
||||||
|
path: "/api/v1/namespaces",
|
||||||
|
expectedHeader: "no-cache, private",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "openapi",
|
||||||
|
path: "/openapi/v2",
|
||||||
|
expectedHeader: "no-cache, private",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "already-set",
|
||||||
|
path: "/api/v1/namespaces",
|
||||||
|
startingHeader: "nonsense",
|
||||||
|
expectedHeader: "nonsense",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
handler := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {
|
||||||
|
//do nothing
|
||||||
|
})
|
||||||
|
wrapped := WithCacheControl(handler)
|
||||||
|
|
||||||
|
testRequest, err := http.NewRequest(http.MethodGet, test.path, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
if len(test.startingHeader) > 0 {
|
||||||
|
w.Header().Set("Cache-Control", test.startingHeader)
|
||||||
|
}
|
||||||
|
|
||||||
|
wrapped.ServeHTTP(w, testRequest)
|
||||||
|
actual := w.Header().Get("Cache-Control")
|
||||||
|
|
||||||
|
if actual != test.expectedHeader {
|
||||||
|
t.Fatal(actual)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -599,6 +599,7 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler {
|
|||||||
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.LongRunningFunc, c.RequestTimeout)
|
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.LongRunningFunc, c.RequestTimeout)
|
||||||
handler = genericfilters.WithWaitGroup(handler, c.LongRunningFunc, c.HandlerChainWaitGroup)
|
handler = genericfilters.WithWaitGroup(handler, c.LongRunningFunc, c.HandlerChainWaitGroup)
|
||||||
handler = genericapifilters.WithRequestInfo(handler, c.RequestInfoResolver)
|
handler = genericapifilters.WithRequestInfo(handler, c.RequestInfoResolver)
|
||||||
|
handler = genericapifilters.WithCacheControl(handler)
|
||||||
handler = genericfilters.WithPanicRecovery(handler)
|
handler = genericfilters.WithPanicRecovery(handler)
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user