diff --git a/core/version.go b/core/version.go index 4a8b04251..ff6f724cc 100644 --- a/core/version.go +++ b/core/version.go @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 /* - Package core contains some basic constants and variables +Package core contains some basic constants and variables */ package core @@ -24,3 +24,6 @@ var KrakendHeaderValue = fmt.Sprintf("Version %s", KrakendVersion) // KrakendUserAgent is the value of the user agent header sent to the backends var KrakendUserAgent = fmt.Sprintf("KrakenD Version %s", KrakendVersion) + +// KrakendHeaders is a flag telling router if it needs to include KrakendHeaderName in the response. +var KrakendHeaders bool = true diff --git a/router/chi/router.go b/router/chi/router.go index 3cd7edfad..2e939ebc7 100644 --- a/router/chi/router.go +++ b/router/chi/router.go @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 /* - Package chi provides some basic implementations for building routers based on go-chi/chi +Package chi provides some basic implementations for building routers based on go-chi/chi */ package chi @@ -13,6 +13,7 @@ import ( "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/luraproject/lura/v2/config" + "github.com/luraproject/lura/v2/core" "github.com/luraproject/lura/v2/logging" "github.com/luraproject/lura/v2/proxy" "github.com/luraproject/lura/v2/router" @@ -97,7 +98,9 @@ func (r chiRouter) Run(cfg config.ServiceConfig) { r.registerKrakendEndpoints(cfg.Endpoints) r.cfg.Engine.NotFound(func(w http.ResponseWriter, r *http.Request) { - w.Header().Set(server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) + if core.KrakendHeaders { + w.Header().Set(server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) + } http.NotFound(w, r) }) diff --git a/router/gin/endpoint.go b/router/gin/endpoint.go index 7bd77abf2..95b4791bc 100644 --- a/router/gin/endpoint.go +++ b/router/gin/endpoint.go @@ -33,6 +33,12 @@ var ErrorResponseWriter = func(c *gin.Context, err error) { // EndpointHandler implements the HandlerFactory interface using the default ToHTTPError function var EndpointHandler = CustomErrorEndpointHandler(logging.NoOp, server.DefaultToHTTPError) +func krakenheader(c *gin.Context, header, value string) { + if core.KrakendHeaders { + c.Header(header, value) + } +} + // CustomErrorEndpointHandler returns a HandlerFactory using the injected ToHTTPError function and logger func CustomErrorEndpointHandler(logger logging.Logger, errF server.ToHTTPError) HandlerFactory { return func(configuration *config.EndpointConfig, prxy proxy.Proxy) gin.HandlerFunc { @@ -45,7 +51,7 @@ func CustomErrorEndpointHandler(logger logging.Logger, errF server.ToHTTPError) return func(c *gin.Context) { requestCtx, cancel := context.WithTimeout(c, configuration.Timeout) - c.Header(core.KrakendHeaderName, core.KrakendHeaderValue) + krakenheader(c, core.KrakendHeaderName, core.KrakendHeaderValue) response, err := prxy(requestCtx, requestGenerator(c, configuration.QueryString)) @@ -74,7 +80,7 @@ func CustomErrorEndpointHandler(logger logging.Logger, errF server.ToHTTPError) } } - c.Header(server.CompleteResponseHeaderName, complete) + krakenheader(c, server.CompleteResponseHeaderName, complete) for _, err := range c.Errors { logger.Error(logPrefix, err.Error()) diff --git a/router/gin/engine.go b/router/gin/engine.go index b75c491a3..c57eb8d15 100644 --- a/router/gin/engine.go +++ b/router/gin/engine.go @@ -81,12 +81,16 @@ func NewEngine(cfg config.ServiceConfig, opt EngineOptions) *gin.Engine { if ginOptions.ObfuscateVersionHeader { core.KrakendHeaderValue = "Version undefined" } + + if ginOptions.RemoveKrakendHeaders { + core.KrakendHeaders = false + } } } } engine.NoRoute(func(c *gin.Context) { - c.Header(server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) + completeHeader(c, server.HeaderIncompleteResponseValue) }) if !ginOptions.DisableAccessLog { @@ -116,6 +120,12 @@ func NewEngine(cfg config.ServiceConfig, opt EngineOptions) *gin.Engine { return engine } +func completeHeader(c *gin.Context, value string) { + if core.KrakendHeaders { + c.Header(server.CompleteResponseHeaderName, value) + } +} + func healthEndpoint(health <-chan string) func(*gin.Context) { mu := new(sync.RWMutex) reports := map[string]string{} @@ -240,6 +250,10 @@ type engineConfiguration struct { // version with the value "undefined" ObfuscateVersionHeader bool `json:"hide_version_header"` + // RemoveKrakendHeaders flags if the X-Krakend and X-Krakend-Completed headers should be included + // in the response/ + RemoveKrakendHeaders bool `json:"remove_krakend_header"` + // UseH2C enable h2c support. UseH2C bool `json:"use_h2c"` } diff --git a/router/gin/router.go b/router/gin/router.go index 21b2fa127..34a29bd31 100644 --- a/router/gin/router.go +++ b/router/gin/router.go @@ -191,7 +191,9 @@ func (r ginRouter) registerOptionEndpoints(rg *gin.RouterGroup) { rg.OPTIONS(path, func(c *gin.Context) { c.Header("Allow", allowed) - c.Header(core.KrakendHeaderName, core.KrakendHeaderValue) + if core.KrakendHeaders { + c.Header(core.KrakendHeaderName, core.KrakendHeaderValue) + } }) } } diff --git a/router/mux/endpoint.go b/router/mux/endpoint.go index 66b21e936..1205ea2e1 100644 --- a/router/mux/endpoint.go +++ b/router/mux/endpoint.go @@ -30,6 +30,12 @@ func CustomEndpointHandler(rb RequestBuilder) HandlerFactory { return CustomEndpointHandlerWithHTTPError(rb, server.DefaultToHTTPError) } +func krakenHeader(w http.ResponseWriter, header, value string) { + if core.KrakendHeaders { + w.Header().Set(header, value) + } +} + // CustomEndpointHandlerWithHTTPError returns a HandlerFactory with the received RequestBuilder func CustomEndpointHandlerWithHTTPError(rb RequestBuilder, errF server.ToHTTPError) HandlerFactory { return func(configuration *config.EndpointConfig, prxy proxy.Proxy) http.HandlerFunc { @@ -44,9 +50,9 @@ func CustomEndpointHandlerWithHTTPError(rb RequestBuilder, errF server.ToHTTPErr method := strings.ToTitle(configuration.Method) return func(w http.ResponseWriter, r *http.Request) { - w.Header().Set(core.KrakendHeaderName, core.KrakendHeaderValue) + krakenHeader(w, core.KrakendHeaderName, core.KrakendHeaderValue) if r.Method != method { - w.Header().Set(server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) + krakenHeader(w, server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) http.Error(w, "", http.StatusMethodNotAllowed) return } @@ -65,12 +71,12 @@ func CustomEndpointHandlerWithHTTPError(rb RequestBuilder, errF server.ToHTTPErr if response != nil && len(response.Data) > 0 { if response.IsComplete { - w.Header().Set(server.CompleteResponseHeaderName, server.HeaderCompleteResponseValue) + krakenHeader(w, server.CompleteResponseHeaderName, server.HeaderCompleteResponseValue) if isCacheEnabled { w.Header().Set("Cache-Control", cacheControlHeaderValue) } } else { - w.Header().Set(server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) + krakenHeader(w, server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) } for k, vs := range response.Metadata.Headers { @@ -79,7 +85,8 @@ func CustomEndpointHandlerWithHTTPError(rb RequestBuilder, errF server.ToHTTPErr } } } else { - w.Header().Set(server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) + krakenHeader(w, server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) + if err != nil { if t, ok := err.(responseError); ok { http.Error(w, err.Error(), t.StatusCode()) diff --git a/router/mux/engine.go b/router/mux/engine.go index ea69fdfb7..f41547e14 100644 --- a/router/mux/engine.go +++ b/router/mux/engine.go @@ -6,6 +6,7 @@ import ( "net/http" "sync" + "github.com/luraproject/lura/v2/core" "github.com/luraproject/lura/v2/transport/http/server" ) @@ -37,7 +38,9 @@ type HTTPErrorInterceptor struct { func (i *HTTPErrorInterceptor) WriteHeader(code int) { i.once.Do(func() { if code != http.StatusOK { - i.ResponseWriter.Header().Set(server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) + if core.KrakendHeaders { + i.ResponseWriter.Header().Set(server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) + } } }) i.ResponseWriter.WriteHeader(code) @@ -73,7 +76,9 @@ func (e *BasicEngine) registrableHandler(pattern string) http.Handler { return } - rw.Header().Set(server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) + if core.KrakendHeaders { + rw.Header().Set(server.CompleteResponseHeaderName, server.HeaderIncompleteResponseValue) + } http.Error(rw, "", http.StatusMethodNotAllowed) }) }