mirror of
https://github.com/zitadel/zitadel.git
synced 2025-03-01 04:27:24 +00:00
fix: do not cache api (incl. grpc) and http errors (#2088)
* fix: add cache-control headers (no-store, no-cache) on grpc (for grpc-web) * fix: do not cache api response (incl. grpc) and http errors
This commit is contained in:
parent
451afada90
commit
bd8133aedd
@ -134,7 +134,6 @@ func createDialOptions(g Gateway) []grpc.DialOption {
|
|||||||
func addInterceptors(handler http.Handler, g Gateway) http.Handler {
|
func addInterceptors(handler http.Handler, g Gateway) http.Handler {
|
||||||
handler = http_mw.DefaultMetricsHandler(handler)
|
handler = http_mw.DefaultMetricsHandler(handler)
|
||||||
handler = http_mw.DefaultTelemetryHandler(handler)
|
handler = http_mw.DefaultTelemetryHandler(handler)
|
||||||
handler = http_mw.NoCacheInterceptor(handler)
|
|
||||||
if interceptor, ok := g.(grpcGatewayCustomInterceptor); ok {
|
if interceptor, ok := g.(grpcGatewayCustomInterceptor); ok {
|
||||||
handler = interceptor.GatewayHTTPInterceptor(handler)
|
handler = interceptor.GatewayHTTPInterceptor(handler)
|
||||||
}
|
}
|
||||||
|
32
internal/api/grpc/server/middleware/cache_interceptor.go
Normal file
32
internal/api/grpc/server/middleware/cache_interceptor.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/caos/logging"
|
||||||
|
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/metadata"
|
||||||
|
|
||||||
|
_ "github.com/caos/zitadel/internal/statik"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NoCacheInterceptor() grpc.UnaryServerInterceptor {
|
||||||
|
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||||
|
headers := map[string]string{
|
||||||
|
"cache-control": "no-store",
|
||||||
|
"expires": time.Now().UTC().Format(http.TimeFormat),
|
||||||
|
"pragma": "no-cache",
|
||||||
|
}
|
||||||
|
header := metadata.New(headers)
|
||||||
|
for key, value := range headers {
|
||||||
|
header.Append(runtime.MetadataHeaderPrefix+key, value)
|
||||||
|
}
|
||||||
|
err := grpc.SendHeader(ctx, header)
|
||||||
|
logging.Log("MIDDLE-efh41").OnError(err).WithField("req", info.FullMethod).Warn("cannot send cache-control on grpc response")
|
||||||
|
resp, err := handler(ctx, req)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
}
|
@ -36,6 +36,7 @@ func CreateServer(verifier *authz.TokenVerifier, authConfig authz.Config, lang l
|
|||||||
middleware.DefaultTracingServer(),
|
middleware.DefaultTracingServer(),
|
||||||
middleware.MetricsHandler(metricTypes, grpc_api.Probes...),
|
middleware.MetricsHandler(metricTypes, grpc_api.Probes...),
|
||||||
middleware.SentryHandler(),
|
middleware.SentryHandler(),
|
||||||
|
middleware.NoCacheInterceptor(),
|
||||||
middleware.ErrorHandler(),
|
middleware.ErrorHandler(),
|
||||||
middleware.AuthorizationInterceptor(verifier, authConfig),
|
middleware.AuthorizationInterceptor(verifier, authConfig),
|
||||||
middleware.TranslationHandler(lang),
|
middleware.TranslationHandler(lang),
|
||||||
|
@ -81,11 +81,29 @@ func AssetsCacheInterceptor(maxAge, sharedMaxAge time.Duration, h http.Handler)
|
|||||||
|
|
||||||
func CacheInterceptorOpts(h http.Handler, cache *Cache) http.Handler {
|
func CacheInterceptorOpts(h http.Handler, cache *Cache) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||||
cache.serializeHeaders(w)
|
cachingResponseWriter := &cachingResponseWriter{
|
||||||
h.ServeHTTP(w, req)
|
ResponseWriter: w,
|
||||||
|
Cache: cache,
|
||||||
|
}
|
||||||
|
h.ServeHTTP(cachingResponseWriter, req)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type cachingResponseWriter struct {
|
||||||
|
http.ResponseWriter
|
||||||
|
*Cache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *cachingResponseWriter) WriteHeader(code int) {
|
||||||
|
if code >= 400 {
|
||||||
|
NeverCacheOptions.serializeHeaders(w.ResponseWriter)
|
||||||
|
w.ResponseWriter.WriteHeader(code)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Cache.serializeHeaders(w.ResponseWriter)
|
||||||
|
w.ResponseWriter.WriteHeader(code)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Cache) serializeHeaders(w http.ResponseWriter) {
|
func (c *Cache) serializeHeaders(w http.ResponseWriter) {
|
||||||
control := make([]string, 0, 6)
|
control := make([]string, 0, 6)
|
||||||
pragma := false
|
pragma := false
|
||||||
|
Loading…
x
Reference in New Issue
Block a user