Skip to main content

pkg/gateway/server/server.go

Source

Overview

What: Wires the public HTTP server for the gateway: routes, middleware, health/readiness handlers, OpenAPI endpoint, metrics, auth protection for upstream proxies, WebSocket limits, and webhook ingestion endpoints.

Why:

The gateway needs a single place where HTTP concerns are composed consistently:

  • request metadata and structured logging
  • security headers and body limits
  • rate limiting and CORS
  • protocol metrics (HTTP/gRPC/WebSockets/SSE)

Keeping this wiring in one package makes runtime composition simple and keeps behavior consistent across entrypoints.

How:

New() constructs the router, initializes proxies/webhooks, mounts routes, then wraps everything in middleware. Start() listens and serves until context cancellation or error, and Shutdown() triggers graceful stop.

Notes: Auth is enforced per-product via buildProtectedHandler (JWT + scope checks). WebSocket limits are enforced before upgrade and tracked through hijack handling.

Contents

Imports

import block 1

pkg/gateway/server/server.go#L7
import (
"context"
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
"strings"
"sync"
"time"

"github.com/rs/cors"

"github.com/theroutercompany/api_router/internal/openapi"
"github.com/theroutercompany/api_router/internal/platform/health"
gatewayauth "github.com/theroutercompany/api_router/pkg/gateway/auth"
gatewayconfig "github.com/theroutercompany/api_router/pkg/gateway/config"
gatewaymetrics "github.com/theroutercompany/api_router/pkg/gateway/metrics"
gatewayproblem "github.com/theroutercompany/api_router/pkg/gateway/problem"
gatewayproxy "github.com/theroutercompany/api_router/pkg/gateway/proxy"
gatewaymiddleware "github.com/theroutercompany/api_router/pkg/gateway/server/middleware"
gatewaywebhook "github.com/theroutercompany/api_router/pkg/gateway/webhook"
pkglog "github.com/theroutercompany/api_router/pkg/log"

"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)

Constants

const block 1

pkg/gateway/server/server.go#L35
const maxRequestBodyBytes int64 = 1 << 20

maxRequestBodyBytes

What: Maximum allowed HTTP request body size (1 MiB).

Why: Prevents large payloads from exhausting memory and protects upstreams from oversized requests.

How: Enforced by the gatewaymiddleware.BodyLimit middleware early in the chain.

Types

type block 1

pkg/gateway/server/server.go#L37
type readinessReporter interface {
Readiness(ctx context.Context) health.Report
}

readinessReporter

What: Minimal interface the server needs for readiness reporting.

Why: Decouples Server from a concrete readiness checker implementation and improves testability.

How: Implemented by internal/platform/health.Checker.

type block 2

pkg/gateway/server/server.go#L42
type Option func(*Server)

Option

What: Functional option type for configuring the Server at construction time.

Why: Keeps the New() signature stable while allowing optional dependencies to be injected.

How: Options mutate fields on the server during New().

type block 3

pkg/gateway/server/server.go#L61
type Server struct {
cfg gatewayconfig.Config
router *http.ServeMux
httpServer *http.Server
handler http.Handler
healthChecker readinessReporter
bootTime time.Time
metricsHandler http.Handler
authenticator *gatewayauth.Authenticator
tradeHandler http.Handler
taskHandler http.Handler
rateLimiter *rateLimiter
cors *cors.Cors
openapiProvider openapi.DocumentProvider
protocolMetrics *protocolMetrics
logger pkglog.Logger
wsLimiter *websocketLimiter
}

Server

What: The primary HTTP server wiring object for the gateway.

Why: Encapsulates configuration, router/middleware setup, proxy handlers, and lifecycle methods.

How: Stores the configured handlers (trade/task/webhooks), shared middleware dependencies (auth, rate limit, CORS, metrics), and exposes Start/Shutdown.

type block 4

pkg/gateway/server/server.go#L372
type deadlineConn struct {
net.Conn
timeout time.Duration
}

deadlineConn

What: A net.Conn wrapper that applies read/write deadlines using a configured timeout.

Why: WebSocket idle timeouts must be enforced at the connection level after hijack.

How: Overrides Read and Write to set deadlines before delegating to the embedded connection.

type block 5

pkg/gateway/server/server.go#L391
type websocketLimiter struct {
limit int
active int
mu sync.Mutex
}

websocketLimiter

What: Concurrency limiter for websocket upgrades.

Why: Protects the gateway from unbounded upgraded connections exhausting file descriptors and memory.

How: Tracks active upgrades under a mutex and returns Acquire/release callbacks.

type block 6

pkg/gateway/server/server.go#L436
type websocketContext struct {
release func()
timeout time.Duration
}

websocketContext

What: Bookkeeping stored in request context for websocket upgrades.

Why: The limiter slot must be released and idle timeout must be applied even after hijack.

How: Carries a release callback and the configured idle timeout.

type block 7

pkg/gateway/server/server.go#L441
type websocketContextKey struct{}

websocketContextKey

What: Context key type used to store websocket context.

Why: Uses a private, unique type to avoid collisions with other context values.

How: Used as the key in context.WithValue.

Functions and Methods

WithOpenAPIProvider

What: Server option that overrides the OpenAPI document provider.

Why: Allows swapping the OpenAPI source (e.g., prebuilt artifact vs dynamic merge service) without changing server code.

How: Sets Server.openapiProvider, which is used by the /openapi.json handler.

pkg/gateway/server/server.go#L45
func WithOpenAPIProvider(provider openapi.DocumentProvider) Option {
return func(s *Server) {
s.openapiProvider = provider
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L46: return func(s *Server) { s.openapiProvider = provider }
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).
    • Nested steps:
      • L46: func(s *Server) { s.openapiProvider = provider }
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L47: s.openapiProvider = provider
            • What: Assigns s.openapiProvider.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.

WithLogger

What: Server option that overrides the logger used by the server.

Why: Allows embedding applications and CLIs to inject their own logger configuration.

How: Sets Server.logger when provided a non-nil logger.

pkg/gateway/server/server.go#L52
func WithLogger(logger pkglog.Logger) Option {
return func(s *Server) {
if logger != nil {
s.logger = logger
}
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L53: return func(s *Server) { if logger != nil { s.logger = logger } }
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).
    • Nested steps:
      • L53: func(s *Server) { if logger != nil { s.logger = logger } }
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L54: if logger != nil { s.logger = logger }
            • What: Branches conditionally.
            • Why: Handles different execution paths based on runtime state.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L55: s.logger = logger
                • What: Assigns s.logger.
                • Why: Keeps intermediate state available for later steps in the function.
                • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.

New

What: Constructs a Server and wires routes + middleware based on gatewayconfig.Config.

Why: Provides a reusable server implementation for the runtime and for embedding.

How: Builds rate limiter/CORS/metrics/auth/OpenAPI provider, initializes proxies/webhooks, mounts routes, then wraps the mux in middleware (body limit, rate limit, CORS, logging, websocket limiting, security headers, request IDs, and h2c).

pkg/gateway/server/server.go#L81
func New(cfg gatewayconfig.Config, checker readinessReporter, registry *gatewaymetrics.Registry, opts ...Option) *Server {
mux := http.NewServeMux()

s := &Server{
cfg: cfg,
router: mux,
healthChecker: checker,
bootTime: time.Now().UTC(),
metricsHandler: nil,
rateLimiter: newRateLimiter(cfg.RateLimit.Window.AsDuration(), cfg.RateLimit.Max),
cors: buildCORS(cfg.CORS.AllowedOrigins),
logger: pkglog.Shared(),
}

for _, opt := range opts {
if opt != nil {
opt(s)
}
}

if s.logger == nil {
s.logger = pkglog.Shared()
}

if registry != nil && cfg.Metrics.Enabled {
s.metricsHandler = registry.Handler()
}
if cfg.Metrics.Enabled {
s.protocolMetrics = newProtocolMetrics(registry)
} else {
s.protocolMetrics = newProtocolMetrics(nil)
}

s.wsLimiter = newWebsocketLimiter(cfg.WebSocket.MaxConcurrent)

if cfg.Auth.Secret != "" {
if authenticator, err := gatewayauth.New(cfg.Auth); err != nil {
s.logger.Errorw("failed to initialize authenticator", "error", err)
} else {
s.authenticator = authenticator
}
}

if s.openapiProvider == nil {
s.openapiProvider = openapi.NewService()
}

s.initProxies()
s.initWebhooks()

s.mountRoutes()
handler := http.Handler(mux)
handler = gatewaymiddleware.BodyLimit(maxRequestBodyBytes, traceIDFromContext, gatewayproblem.Write)(handler)
if s.rateLimiter != nil {
handler = gatewaymiddleware.RateLimit(
func(key string, now time.Time) bool { return s.rateLimiter.allow(key, now) },
clientKey,
time.Now,
traceIDFromContext,
gatewayproblem.Write,
)(handler)
}
if s.cors != nil {
handler = gatewaymiddleware.CORS(s.cors, traceIDFromContext, gatewayproblem.Write)(handler)
}
var tracker gatewaymiddleware.TrackFunc
var hijacker gatewaymiddleware.HijackedFunc
if s.protocolMetrics != nil || s.wsLimiter != nil {
tracker = s.trackRequest
hijacker = s.hijackedRequest
}
handler = gatewaymiddleware.Logging(s.logger, tracker, hijacker, requestIDFromContext, traceIDFromContext, clientAddress)(handler)
if s.wsLimiter != nil {
handler = websocketLimitMiddleware(s.wsLimiter, s.cfg.WebSocket.IdleTimeout.AsDuration(), traceIDFromContext, gatewayproblem.Write, s.logger)(handler)
}
handler = gatewaymiddleware.SecurityHeaders()(handler)
handler = gatewaymiddleware.RequestMetadata(ensureRequestIDs)(handler)
http2Server := &http2.Server{}
handler = h2c.NewHandler(handler, http2Server)

s.handler = handler
s.httpServer = &http.Server{
Addr: fmt.Sprintf(":%d", cfg.HTTP.Port),
Handler: handler,
}
if err := http2.ConfigureServer(s.httpServer, http2Server); err != nil {
s.logger.Errorw("failed to configure http2 server", "error", err)
}

return s
}

Walkthrough

Expand walkthrough (49 steps)

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L82: mux := http.NewServeMux()
    • What: Defines mux.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L84: s := &Server{ cfg: cfg, router: mux, healthChecker: checker, bootTime: time.Now().UTC(), metricsHandler: nil, rateLimiter: newRateLimiter(c…
    • What: Defines s.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L95: for _, opt := range opts { if opt != nil { opt(s) } }
    • What: Iterates over a collection.
    • Why: Processes multiple elements with the same logic.
    • How: Executes a for ... range loop.
    • Nested steps:
      • L96: if opt != nil { opt(s) }
        • What: Branches conditionally.
        • Why: Handles different execution paths based on runtime state.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L97: opt(s)
            • What: Calls opt.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
  • L101: if s.logger == nil { s.logger = pkglog.Shared() }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L102: s.logger = pkglog.Shared()
        • What: Assigns s.logger.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L105: if registry != nil && cfg.Metrics.Enabled { s.metricsHandler = registry.Handler() }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L106: s.metricsHandler = registry.Handler()
        • What: Assigns s.metricsHandler.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L108: if cfg.Metrics.Enabled { s.protocolMetrics = newProtocolMetrics(registry) } else { s.protocolMetrics = newProtocolMetrics(nil) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L109: s.protocolMetrics = newProtocolMetrics(registry)
        • What: Assigns s.protocolMetrics.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L111: s.protocolMetrics = newProtocolMetrics(nil)
        • What: Assigns s.protocolMetrics.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L114: s.wsLimiter = newWebsocketLimiter(cfg.WebSocket.MaxConcurrent)
    • What: Assigns s.wsLimiter.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L116: if cfg.Auth.Secret != "" { if authenticator, err := gatewayauth.New(cfg.Auth); err != nil { s.logger.Errorw("failed to initialize authentic…
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L117: if authenticator, err := gatewayauth.New(cfg.Auth); err != nil { s.logger.Errorw("failed to initialize authenticator", "error", err) } else…
        • What: Branches conditionally.
        • Why: Handles different execution paths based on runtime state.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L117: authenticator, err := gatewayauth.New(cfg.Auth)
            • What: Defines authenticator, err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L118: s.logger.Errorw("failed to initialize authenticator", "error", err)
            • What: Calls s.logger.Errorw.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L120: s.authenticator = authenticator
            • What: Assigns s.authenticator.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L124: if s.openapiProvider == nil { s.openapiProvider = openapi.NewService() }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L125: s.openapiProvider = openapi.NewService()
        • What: Assigns s.openapiProvider.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L128: s.initProxies()
    • What: Calls s.initProxies.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L129: s.initWebhooks()
    • What: Calls s.initWebhooks.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L131: s.mountRoutes()
    • What: Calls s.mountRoutes.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L132: handler := http.Handler(mux)
    • What: Defines handler.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L133: handler = gatewaymiddleware.BodyLimit(maxRequestBodyBytes, traceIDFromContext, gatewayproblem.Write)(handler)
    • What: Assigns handler.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L134: if s.rateLimiter != nil { handler = gatewaymiddleware.RateLimit( func(key string, now time.Time) bool { return s.rateLimiter.allow(key, now…
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L135: handler = gatewaymiddleware.RateLimit( func(key string, now time.Time) bool { return s.rateLimiter.allow(key, now) }, clientKey, time.Now, …
        • What: Assigns handler.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
        • Nested steps:
          • L136: func(key string, now time.Time) bool { return s.rateLimiter.allow(key, now) }
            • What: Defines an inline function (closure).
            • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
            • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
            • Nested steps:
              • L136: return s.rateLimiter.allow(key, now)
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
  • L143: if s.cors != nil { handler = gatewaymiddleware.CORS(s.cors, traceIDFromContext, gatewayproblem.Write)(handler) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L144: handler = gatewaymiddleware.CORS(s.cors, traceIDFromContext, gatewayproblem.Write)(handler)
        • What: Assigns handler.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L146: var tracker gatewaymiddleware.TrackFunc
    • What: Declares local names.
    • Why: Introduces variables or types used later in the function.
    • How: Executes a Go declaration statement inside the function body.
  • L147: var hijacker gatewaymiddleware.HijackedFunc
    • What: Declares local names.
    • Why: Introduces variables or types used later in the function.
    • How: Executes a Go declaration statement inside the function body.
  • L148: if s.protocolMetrics != nil || s.wsLimiter != nil { tracker = s.trackRequest hijacker = s.hijackedRequest }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L149: tracker = s.trackRequest
        • What: Assigns tracker.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L150: hijacker = s.hijackedRequest
        • What: Assigns hijacker.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L152: handler = gatewaymiddleware.Logging(s.logger, tracker, hijacker, requestIDFromContext, traceIDFromContext, clientAddress)(handler)
    • What: Assigns handler.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L153: if s.wsLimiter != nil { handler = websocketLimitMiddleware(s.wsLimiter, s.cfg.WebSocket.IdleTimeout.AsDuration(), traceIDFromContext, gatew…
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L154: handler = websocketLimitMiddleware(s.wsLimiter, s.cfg.WebSocket.IdleTimeout.AsDuration(), traceIDFromContext, gatewayproblem.Write, s.logge…
        • What: Assigns handler.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L156: handler = gatewaymiddleware.SecurityHeaders()(handler)
    • What: Assigns handler.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L157: handler = gatewaymiddleware.RequestMetadata(ensureRequestIDs)(handler)
    • What: Assigns handler.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L158: http2Server := &http2.Server{}
    • What: Defines http2Server.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L159: handler = h2c.NewHandler(handler, http2Server)
    • What: Assigns handler.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L161: s.handler = handler
    • What: Assigns s.handler.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L162: s.httpServer = &http.Server{ Addr: fmt.Sprintf(":%d", cfg.HTTP.Port), Handler: handler, }
    • What: Assigns s.httpServer.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L166: if err := http2.ConfigureServer(s.httpServer, http2Server); err != nil { s.logger.Errorw("failed to configure http2 server", "error", err) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L166: err := http2.ConfigureServer(s.httpServer, http2Server)
        • What: Defines err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L167: s.logger.Errorw("failed to configure http2 server", "error", err)
        • What: Calls s.logger.Errorw.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
  • L170: return s
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

(*Server).Start

What: Starts listening and serving until context cancellation or server error.

Why: Separates serving from construction so runtime code can control lifecycle.

How: Runs ListenAndServe in a goroutine, then either shuts down on context cancellation (using configured shutdown timeout) or returns on server error.

pkg/gateway/server/server.go#L174
func (s *Server) Start(ctx context.Context) error {
if s.httpServer == nil {
return errors.New("http server not initialised")
}

errCh := make(chan error, 1)
go func() {
s.logger.Infow("http server listening", "addr", s.httpServer.Addr)
if err := s.httpServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
errCh <- err
}
close(errCh)
}()

select {
case <-ctx.Done():
shutdownCtx, cancel := context.WithTimeout(context.Background(), s.cfg.HTTP.ShutdownTimeout.AsDuration())
defer cancel()
if err := s.httpServer.Shutdown(shutdownCtx); err != nil {
s.logger.Errorw("http server shutdown failed", "error", err)
return err
}
return ctx.Err()
case err := <-errCh:
if err != nil {
s.logger.Errorw("http server stopped with error", "error", err)
}
return err
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L175: if s.httpServer == nil { return errors.New("http server not initialised") }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L176: return errors.New("http server not initialised")
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L179: errCh := make(chan error, 1)
    • What: Defines errCh.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L180: go func() { s.logger.Infow("http server listening", "addr", s.httpServer.Addr) if err := s.httpServer.ListenAndServe(); err != nil && !erro…
    • What: Starts a goroutine.
    • Why: Runs work concurrently.
    • How: Invokes the function call asynchronously using go.
    • Nested steps:
      • L180: func() { s.logger.Infow("http server listening", "addr", s.httpServer.Addr) if err := s.httpServer.ListenAndServe(); err != nil && !errors.…
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L181: s.logger.Infow("http server listening", "addr", s.httpServer.Addr)
            • What: Calls s.logger.Infow.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L182: if err := s.httpServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { errCh <- err }
            • What: Branches conditionally.
            • Why: Handles different execution paths based on runtime state.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L182: err := s.httpServer.ListenAndServe()
                • What: Defines err.
                • Why: Keeps intermediate state available for later steps in the function.
                • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
              • L183: errCh <- err
                • What: Sends a value on a channel.
                • Why: Communicates with another goroutine.
                • How: Executes a channel send operation.
          • L185: close(errCh)
            • What: Calls close.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
  • L188: select { case <-ctx.Done(): shutdownCtx, cancel := context.WithTimeout(context.Background(), s.cfg.HTTP.ShutdownTimeout.AsDuration()) defer…
    • What: Selects among concurrent operations.
    • Why: Coordinates channel operations without blocking incorrectly.
    • How: Executes a select statement and runs one ready case.
    • Nested steps:
      • L189: case <-ctx.Done():
        • What: Selects a select-case branch.
        • Why: Coordinates concurrent operations without blocking incorrectly.
        • How: Runs this case body when its channel operation is ready (or runs default immediately).
        • Nested steps:
          • L190: shutdownCtx, cancel := context.WithTimeout(context.Background(), s.cfg.HTTP.ShutdownTimeout.AsDuration())
            • What: Defines shutdownCtx, cancel.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L191: defer cancel()
            • What: Defers a call for cleanup.
            • Why: Ensures the deferred action runs even on early returns.
            • How: Schedules the call to run when the surrounding function returns.
          • L192: if err := s.httpServer.Shutdown(shutdownCtx); err != nil { s.logger.Errorw("http server shutdown failed", "error", err) return err }
            • What: Branches conditionally.
            • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L192: err := s.httpServer.Shutdown(shutdownCtx)
                • What: Defines err.
                • Why: Keeps intermediate state available for later steps in the function.
                • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
              • L193: s.logger.Errorw("http server shutdown failed", "error", err)
                • What: Calls s.logger.Errorw.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
              • L194: return err
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
          • L196: return ctx.Err()
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
      • L197: case err := <-errCh:
        • What: Selects a select-case branch.
        • Why: Coordinates concurrent operations without blocking incorrectly.
        • How: Runs this case body when its channel operation is ready (or runs default immediately).
        • Nested steps:
          • L198: if err != nil { s.logger.Errorw("http server stopped with error", "error", err) }
            • What: Branches conditionally.
            • Why: Handles different execution paths based on runtime state.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L199: s.logger.Errorw("http server stopped with error", "error", err)
                • What: Calls s.logger.Errorw.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
          • L201: return err
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).

(*Server).Shutdown

What: Gracefully stops the underlying HTTP server.

Why: Provides a clean shutdown path for the runtime and embedding.

How: Delegates to http.Server.Shutdown(ctx) when initialized.

pkg/gateway/server/server.go#L206
func (s *Server) Shutdown(ctx context.Context) error {
if s.httpServer == nil {
return nil
}
return s.httpServer.Shutdown(ctx)
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L207: if s.httpServer == nil { return nil }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L208: return nil
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L210: return s.httpServer.Shutdown(ctx)
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

(*Server).mountRoutes

What: Mounts the fixed gateway routes on the internal http.ServeMux.

Why: Keeps route registration centralized and predictable.

How: Registers /health, readiness endpoints, /openapi.json, /metrics, and /v1/{trade,task} proxy prefixes when handlers are configured.

pkg/gateway/server/server.go#L213
func (s *Server) mountRoutes() {
s.router.HandleFunc("/health", s.handleHealth)
s.router.HandleFunc("/readyz", s.handleReadiness)
s.router.HandleFunc("/readiness", s.handleReadiness)
if s.openapiProvider != nil {
s.router.HandleFunc("/openapi.json", s.handleOpenAPI)
}
if s.metricsHandler != nil {
s.router.Handle("/metrics", s.metricsHandler)
}
if s.tradeHandler != nil {
s.router.Handle("/v1/trade", s.tradeHandler)
s.router.Handle("/v1/trade/", s.tradeHandler)
}
if s.taskHandler != nil {
s.router.Handle("/v1/task", s.taskHandler)
s.router.Handle("/v1/task/", s.taskHandler)
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L214: s.router.HandleFunc("/health", s.handleHealth)
    • What: Calls s.router.HandleFunc.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L215: s.router.HandleFunc("/readyz", s.handleReadiness)
    • What: Calls s.router.HandleFunc.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L216: s.router.HandleFunc("/readiness", s.handleReadiness)
    • What: Calls s.router.HandleFunc.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L217: if s.openapiProvider != nil { s.router.HandleFunc("/openapi.json", s.handleOpenAPI) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L218: s.router.HandleFunc("/openapi.json", s.handleOpenAPI)
        • What: Calls s.router.HandleFunc.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
  • L220: if s.metricsHandler != nil { s.router.Handle("/metrics", s.metricsHandler) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L221: s.router.Handle("/metrics", s.metricsHandler)
        • What: Calls s.router.Handle.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
  • L223: if s.tradeHandler != nil { s.router.Handle("/v1/trade", s.tradeHandler) s.router.Handle("/v1/trade/", s.tradeHandler) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L224: s.router.Handle("/v1/trade", s.tradeHandler)
        • What: Calls s.router.Handle.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L225: s.router.Handle("/v1/trade/", s.tradeHandler)
        • What: Calls s.router.Handle.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
  • L227: if s.taskHandler != nil { s.router.Handle("/v1/task", s.taskHandler) s.router.Handle("/v1/task/", s.taskHandler) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L228: s.router.Handle("/v1/task", s.taskHandler)
        • What: Calls s.router.Handle.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L229: s.router.Handle("/v1/task/", s.taskHandler)
        • What: Calls s.router.Handle.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.

(*Server).initProxies

What: Builds upstream reverse proxy handlers from config and wires them into trade/task routes.

Why: Proxy behavior is shared, but each product needs its own target base URL and auth scopes.

How: Iterates configured readiness upstreams, creates a gatewayproxy handler per upstream, then assigns protected handlers for trade and task.

pkg/gateway/server/server.go#L233
func (s *Server) initProxies() {
for _, upstream := range s.cfg.Readiness.Upstreams {
handler, err := gatewayproxy.New(gatewayproxy.Options{
Target: upstream.BaseURL,
Product: upstream.Name,
TLS: gatewayproxy.TLSConfig{
Enabled: upstream.TLS.Enabled,
InsecureSkipVerify: upstream.TLS.InsecureSkipVerify,
CAFile: upstream.TLS.CAFile,
ClientCertFile: upstream.TLS.ClientCertFile,
ClientKeyFile: upstream.TLS.ClientKeyFile,
},
})
if err != nil {
s.logger.Errorw("failed to build proxy", "error", err, "upstream", upstream.Name)
continue
}

switch upstream.Name {
case "trade":
s.tradeHandler = s.buildProtectedHandler("trade", []string{"trade.read", "trade.write"}, handler)
case "task":
s.taskHandler = s.buildProtectedHandler("task", []string{"task.read", "task.write"}, handler)
}
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L234: for _, upstream := range s.cfg.Readiness.Upstreams { handler, err := gatewayproxy.New(gatewayproxy.Options{ Target: upstream.BaseURL, Produ…
    • What: Iterates over a collection.
    • Why: Processes multiple elements with the same logic.
    • How: Executes a for ... range loop.
    • Nested steps:
      • L235: handler, err := gatewayproxy.New(gatewayproxy.Options{ Target: upstream.BaseURL, Product: upstream.Name, TLS: gatewayproxy.TLSConfig{ Enabl…
        • What: Defines handler, err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L246: if err != nil { s.logger.Errorw("failed to build proxy", "error", err, "upstream", upstream.Name) continue }
        • What: Branches conditionally.
        • Why: Handles different execution paths based on runtime state.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L247: s.logger.Errorw("failed to build proxy", "error", err, "upstream", upstream.Name)
            • What: Calls s.logger.Errorw.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L248: continue
            • What: Executes a statement.
            • Why: Advances the function logic.
            • How: Runs this statement as part of the function body.
      • L251: switch upstream.Name { case "trade": s.tradeHandler = s.buildProtectedHandler("trade", []string{"trade.read", "trade.write"}, handler) case…
        • What: Selects a branch from multiple cases.
        • Why: Keeps multi-case branching readable and explicit.
        • How: Evaluates the switch expression and executes the first matching case.
        • Nested steps:
          • L252: case "trade":
            • What: Selects a switch case.
            • Why: Makes multi-branch control flow explicit and readable.
            • How: Runs this case body when the switch value matches (or when default is selected).
            • Nested steps:
              • L253: s.tradeHandler = s.buildProtectedHandler("trade", []string{"trade.read", "trade.write"}, handler)
                • What: Assigns s.tradeHandler.
                • Why: Keeps intermediate state available for later steps in the function.
                • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L254: case "task":
            • What: Selects a switch case.
            • Why: Makes multi-branch control flow explicit and readable.
            • How: Runs this case body when the switch value matches (or when default is selected).
            • Nested steps:
              • L255: s.taskHandler = s.buildProtectedHandler("task", []string{"task.read", "task.write"}, handler)
                • What: Assigns s.taskHandler.
                • Why: Keeps intermediate state available for later steps in the function.
                • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.

(*Server).initWebhooks

What: Registers webhook ingestion endpoints when enabled in config.

Why: Allows external systems to deliver event callbacks to the gateway, which then forwards them securely to target upstreams.

How: For each configured endpoint, constructs gatewaywebhook.Options, builds a handler, mounts it at the configured path, and logs registration.

pkg/gateway/server/server.go#L260
func (s *Server) initWebhooks() {
if !s.cfg.Webhooks.Enabled {
return
}
if len(s.cfg.Webhooks.Endpoints) == 0 {
return
}
for _, endpoint := range s.cfg.Webhooks.Endpoints {
opts := gatewaywebhook.Options{
Name: endpoint.Name,
Path: endpoint.Path,
TargetURL: endpoint.TargetURL,
Secret: endpoint.Secret,
SignatureHeader: endpoint.SignatureHeader,
MaxAttempts: endpoint.MaxAttempts,
InitialBackoff: endpoint.InitialBackoff.AsDuration(),
Timeout: endpoint.Timeout.AsDuration(),
Client: &http.Client{
Timeout: endpoint.Timeout.AsDuration(),
},
Logger: s.logger,
}
handler, err := gatewaywebhook.New(opts)
if err != nil {
s.logger.Errorw("failed to initialise webhook handler", "error", err, "webhook", endpoint.Name)
continue
}
s.router.Handle(endpoint.Path, handler)
s.logger.Infow("registered webhook endpoint", "webhook", endpoint.Name, "path", endpoint.Path)
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L261: if !s.cfg.Webhooks.Enabled { return }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L262: return
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L264: if len(s.cfg.Webhooks.Endpoints) == 0 { return }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L265: return
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L267: for _, endpoint := range s.cfg.Webhooks.Endpoints { opts := gatewaywebhook.Options{ Name: endpoint.Name, Path: endpoint.Path, TargetURL: en…
    • What: Iterates over a collection.
    • Why: Processes multiple elements with the same logic.
    • How: Executes a for ... range loop.
    • Nested steps:
      • L268: opts := gatewaywebhook.Options{ Name: endpoint.Name, Path: endpoint.Path, TargetURL: endpoint.TargetURL, Secret: endpoint.Secret, Signature…
        • What: Defines opts.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L282: handler, err := gatewaywebhook.New(opts)
        • What: Defines handler, err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L283: if err != nil { s.logger.Errorw("failed to initialise webhook handler", "error", err, "webhook", endpoint.Name) continue }
        • What: Branches conditionally.
        • Why: Handles different execution paths based on runtime state.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L284: s.logger.Errorw("failed to initialise webhook handler", "error", err, "webhook", endpoint.Name)
            • What: Calls s.logger.Errorw.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L285: continue
            • What: Executes a statement.
            • Why: Advances the function logic.
            • How: Runs this statement as part of the function body.
      • L287: s.router.Handle(endpoint.Path, handler)
        • What: Calls s.router.Handle.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L288: s.logger.Infow("registered webhook endpoint", "webhook", endpoint.Name, "path", endpoint.Path)
        • What: Calls s.logger.Infow.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.

(*Server).trackRequest

What: Integrates request completion tracking for protocol metrics and websocket limiter release.

Why: Normal HTTP requests complete with a status code, but websocket upgrades need limiter release when the request lifecycle ends.

How: Wraps protocolMetrics.track (if enabled) and releases websocket capacity (if the request carried websocket context) when the returned closure is invoked.

pkg/gateway/server/server.go#L292
func (s *Server) trackRequest(r *http.Request) func(status int, elapsed time.Duration) {
var track func(int, time.Duration)
if s.protocolMetrics != nil {
track = s.protocolMetrics.track(r)
}
wc, ok := websocketContextFromRequest(r)
return func(status int, elapsed time.Duration) {
if track != nil {
track(status, elapsed)
}
if ok {
wc.release()
}
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L293: var track func(int, time.Duration)
    • What: Declares local names.
    • Why: Introduces variables or types used later in the function.
    • How: Executes a Go declaration statement inside the function body.
  • L294: if s.protocolMetrics != nil { track = s.protocolMetrics.track(r) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L295: track = s.protocolMetrics.track(r)
        • What: Assigns track.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L297: wc, ok := websocketContextFromRequest(r)
    • What: Defines wc, ok.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L298: return func(status int, elapsed time.Duration) { if track != nil { track(status, elapsed) } if ok { wc.release() } }
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).
    • Nested steps:
      • L298: func(status int, elapsed time.Duration) { if track != nil { track(status, elapsed) } if ok { wc.release() } }
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L299: if track != nil { track(status, elapsed) }
            • What: Branches conditionally.
            • Why: Handles different execution paths based on runtime state.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L300: track(status, elapsed)
                • What: Calls track.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
          • L302: if ok { wc.release() }
            • What: Branches conditionally.
            • Why: Handles different execution paths based on runtime state.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L303: wc.release()
                • What: Calls wc.release.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.

(*Server).hijackedRequest

What: Integrates hijack tracking for protocol metrics and websocket capacity release/idle timeout.

Why: WebSockets and other upgraded connections bypass normal response completion; metrics and limits must be tracked via Hijack().

How: Combines protocol-metrics closer (if enabled) with websocket limiter release, and provides an optional net.Conn wrapper that applies idle deadlines.

pkg/gateway/server/server.go#L308
func (s *Server) hijackedRequest(r *http.Request) (func(), func(net.Conn) net.Conn) {
var metricsCloser func()
if s.protocolMetrics != nil {
metricsCloser = s.protocolMetrics.hijacked(r)
}
wc, ok := websocketContextFromRequest(r)
if !ok {
return metricsCloser, nil
}
release := wc.release
if release == nil {
release = func() {}
}
combined := func() {
release()
if metricsCloser != nil {
metricsCloser()
}
}
return combined, func(conn net.Conn) net.Conn {
if wc.timeout <= 0 {
return conn
}
return &deadlineConn{Conn: conn, timeout: wc.timeout}
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L309: var metricsCloser func()
    • What: Declares local names.
    • Why: Introduces variables or types used later in the function.
    • How: Executes a Go declaration statement inside the function body.
  • L310: if s.protocolMetrics != nil { metricsCloser = s.protocolMetrics.hijacked(r) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L311: metricsCloser = s.protocolMetrics.hijacked(r)
        • What: Assigns metricsCloser.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L313: wc, ok := websocketContextFromRequest(r)
    • What: Defines wc, ok.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L314: if !ok { return metricsCloser, nil }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L315: return metricsCloser, nil
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L317: release := wc.release
    • What: Defines release.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L318: if release == nil { release = func() {} }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L319: release = func() {}
        • What: Assigns release.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
        • Nested steps:
          • L319: func() {}
            • What: Defines an inline function (closure).
            • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
            • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
  • L321: combined := func() { release() if metricsCloser != nil { metricsCloser() } }
    • What: Defines combined.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
    • Nested steps:
      • L321: func() { release() if metricsCloser != nil { metricsCloser() } }
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L322: release()
            • What: Calls release.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L323: if metricsCloser != nil { metricsCloser() }
            • What: Branches conditionally.
            • Why: Handles different execution paths based on runtime state.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L324: metricsCloser()
                • What: Calls metricsCloser.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
  • L327: return combined, func(conn net.Conn) net.Conn { if wc.timeout <= 0 { return conn } return &deadlineConn{Conn: conn, timeout: wc.timeout} }
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).
    • Nested steps:
      • L327: func(conn net.Conn) net.Conn { if wc.timeout <= 0 { return conn } return &deadlineConn{Conn: conn, timeout: wc.timeout} }
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L328: if wc.timeout <= 0 { return conn }
            • What: Branches conditionally.
            • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L329: return conn
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
          • L331: return &deadlineConn{Conn: conn, timeout: wc.timeout}
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).

websocketLimitMiddleware

What: Middleware that enforces websocket concurrency limits and stores websocket bookkeeping in request context.

Why: Upgraded connections are long-lived; limiting upgrades prevents resource exhaustion.

How: For websocket requests, acquires the limiter and rejects with 503 on exhaustion; otherwise stores a release func + idle timeout in context for downstream tracking.

pkg/gateway/server/server.go#L335
func websocketLimitMiddleware(limiter *websocketLimiter, timeout time.Duration, trace gatewaymiddleware.TraceIDFromContext, write gatewaymiddleware.ProblemWriter, logger pkglog.Logger) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
if limiter == nil || next == nil {
return next
}
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !isWebSocketRequest(r) {
next.ServeHTTP(w, r)
return
}

release, ok := limiter.Acquire()
if !ok {
if write != nil {
tid := ""
if trace != nil {
tid = trace(r.Context())
}
write(w, http.StatusServiceUnavailable, "WebSocket Limit Reached", "Gateway is at websocket capacity", tid, r.URL.Path)
} else {
http.Error(w, http.StatusText(http.StatusServiceUnavailable), http.StatusServiceUnavailable)
}
if logger != nil {
logger.Warnw("websocket connection rejected", "limit", limiter.limit)
}
return
}

ctx := context.WithValue(r.Context(), websocketContextKey{}, websocketContext{
release: release,
timeout: timeout,
})
next.ServeHTTP(w, r.WithContext(ctx))
})
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L336: return func(next http.Handler) http.Handler { if limiter == nil || next == nil { return next } return http.HandlerFunc(func(w http.Response…
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).
    • Nested steps:
      • L336: func(next http.Handler) http.Handler { if limiter == nil || next == nil { return next } return http.HandlerFunc(func(w http.ResponseWriter,…
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L337: if limiter == nil || next == nil { return next }
            • What: Branches conditionally.
            • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L338: return next
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
          • L340: return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if !isWebSocketRequest(r) { next.ServeHTTP(w, r) return } release, o…
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
            • Nested steps:
              • L340: func(w http.ResponseWriter, r *http.Request) { if !isWebSocketRequest(r) { next.ServeHTTP(w, r) return } release, ok := limiter.Acquire() i…
                • What: Defines an inline function (closure).
                • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
                • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
                • Nested steps:
                  • L341: if !isWebSocketRequest(r) { next.ServeHTTP(w, r) return }
                    • What: Branches conditionally.
                    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
                    • How: Evaluates the condition and executes the matching branch.
                    • Nested steps:
                      • L342: next.ServeHTTP(w, r)
                        • What: Calls next.ServeHTTP.
                        • Why: Performs side effects or delegates work to a helper.
                        • How: Executes the expression statement.
                      • L343: return
                        • What: Returns from the current function.
                        • Why: Ends the current execution path and hands control back to the caller.
                        • How: Executes a return statement (possibly returning values).
                  • L346: release, ok := limiter.Acquire()
                    • What: Defines release, ok.
                    • Why: Keeps intermediate state available for later steps in the function.
                    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
                  • L347: if !ok { if write != nil { tid := "" if trace != nil { tid = trace(r.Context()) } write(w, http.StatusServiceUnavailable, "WebSocket Limit …
                    • What: Branches conditionally.
                    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
                    • How: Evaluates the condition and executes the matching branch.
                    • Nested steps:
                      • L348: if write != nil { tid := "" if trace != nil { tid = trace(r.Context()) } write(w, http.StatusServiceUnavailable, "WebSocket Limit Reached",…
                        • What: Branches conditionally.
                        • Why: Handles different execution paths based on runtime state.
                        • How: Evaluates the condition and executes the matching branch.
                        • Nested steps:
                          • L349: tid := ""
                            • What: Defines tid.
                            • Why: Keeps intermediate state available for later steps in the function.
                            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
                          • L350: if trace != nil { tid = trace(r.Context()) }
                            • What: Branches conditionally.
                            • Why: Handles different execution paths based on runtime state.
                            • How: Evaluates the condition and executes the matching branch.
                          • L353: write(w, http.StatusServiceUnavailable, "WebSocket Limit Reached", "Gateway is at websocket capacity", tid, r.URL.Path)
                            • What: Calls write.
                            • Why: Performs side effects or delegates work to a helper.
                            • How: Executes the expression statement.
                          • L355: http.Error(w, http.StatusText(http.StatusServiceUnavailable), http.StatusServiceUnavailable)
                            • What: Calls http.Error.
                            • Why: Performs side effects or delegates work to a helper.
                            • How: Executes the expression statement.
                      • L357: if logger != nil { logger.Warnw("websocket connection rejected", "limit", limiter.limit) }
                        • What: Branches conditionally.
                        • Why: Handles different execution paths based on runtime state.
                        • How: Evaluates the condition and executes the matching branch.
                        • Nested steps:
                          • L358: logger.Warnw("websocket connection rejected", "limit", limiter.limit)
                            • What: Calls logger.Warnw.
                            • Why: Performs side effects or delegates work to a helper.
                            • How: Executes the expression statement.
                      • L360: return
                        • What: Returns from the current function.
                        • Why: Ends the current execution path and hands control back to the caller.
                        • How: Executes a return statement (possibly returning values).
                  • L363: ctx := context.WithValue(r.Context(), websocketContextKey{}, websocketContext{ release: release, timeout: timeout, })
                    • What: Defines ctx.
                    • Why: Keeps intermediate state available for later steps in the function.
                    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
                  • L367: next.ServeHTTP(w, r.WithContext(ctx))
                    • What: Calls next.ServeHTTP.
                    • Why: Performs side effects or delegates work to a helper.
                    • How: Executes the expression statement.

(*deadlineConn).Read

What: Wraps net.Conn.Read with a per-operation read deadline.

Why: Enforces websocket idle timeout by timing out reads on inactive connections.

How: Sets SetReadDeadline(now + timeout) before delegating to the underlying connection.

pkg/gateway/server/server.go#L377
func (c *deadlineConn) Read(b []byte) (int, error) {
if c.timeout > 0 {
_ = c.Conn.SetReadDeadline(time.Now().Add(c.timeout))
}
return c.Conn.Read(b)
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L378: if c.timeout > 0 { _ = c.Conn.SetReadDeadline(time.Now().Add(c.timeout)) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L379: _ = c.Conn.SetReadDeadline(time.Now().Add(c.timeout))
        • What: Assigns _.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L381: return c.Conn.Read(b)
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

(*deadlineConn).Write

What: Wraps net.Conn.Write with a per-operation write deadline.

Why: Prevents writes from blocking forever on idle or stalled websocket connections.

How: Sets SetWriteDeadline(now + timeout) before delegating to the underlying connection.

pkg/gateway/server/server.go#L384
func (c *deadlineConn) Write(b []byte) (int, error) {
if c.timeout > 0 {
_ = c.Conn.SetWriteDeadline(time.Now().Add(c.timeout))
}
return c.Conn.Write(b)
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L385: if c.timeout > 0 { _ = c.Conn.SetWriteDeadline(time.Now().Add(c.timeout)) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L386: _ = c.Conn.SetWriteDeadline(time.Now().Add(c.timeout))
        • What: Assigns _.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L388: return c.Conn.Write(b)
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

newWebsocketLimiter

What: Constructs a websocketLimiter for the configured max concurrency.

Why: Encapsulates websocket capacity logic in a single component.

How: Returns a limiter with the provided limit; 0 or negative values are treated as unlimited by Acquire().

pkg/gateway/server/server.go#L397
func newWebsocketLimiter(limit int) *websocketLimiter {
return &websocketLimiter{limit: limit}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L398: return &websocketLimiter{limit: limit}
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

(*websocketLimiter).Acquire

What: Attempts to acquire a websocket slot and returns a release function when successful.

Why: Provides bounded concurrency for upgrades and ensures capacity is returned exactly once.

How: If unlimited, returns an always-ok release; otherwise increments an internal counter under mutex and returns a sync.Once-guarded release that decrements.

pkg/gateway/server/server.go#L401
func (l *websocketLimiter) Acquire() (func(), bool) {
if l == nil {
return func() {}, true
}
if l.limit <= 0 {
var once sync.Once
return func() { once.Do(func() {}) }, true
}
l.mu.Lock()
defer l.mu.Unlock()
if l.active >= l.limit {
return nil, false
}
l.active++
var once sync.Once
return func() {
once.Do(func() {
l.mu.Lock()
l.active--
l.mu.Unlock()
})
}, true
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L402: if l == nil { return func() {}, true }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L403: return func() {}, true
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
        • Nested steps:
          • L403: func() {}
            • What: Defines an inline function (closure).
            • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
            • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
  • L405: if l.limit <= 0 { var once sync.Once return func() { once.Do(func() {}) }, true }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L406: var once sync.Once
        • What: Declares local names.
        • Why: Introduces variables or types used later in the function.
        • How: Executes a Go declaration statement inside the function body.
      • L407: return func() { once.Do(func() {}) }, true
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
        • Nested steps:
          • L407: func() { once.Do(func() {}) }
            • What: Defines an inline function (closure).
            • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
            • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
            • Nested steps:
              • L407: once.Do(func() {})
                • What: Calls once.Do.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
                • Nested steps:
                  • L407: func() {}
                    • What: Defines an inline function (closure).
                    • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
                    • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
  • L409: l.mu.Lock()
    • What: Calls l.mu.Lock.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L410: defer l.mu.Unlock()
    • What: Defers a call for cleanup.
    • Why: Ensures the deferred action runs even on early returns.
    • How: Schedules the call to run when the surrounding function returns.
  • L411: if l.active >= l.limit { return nil, false }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L412: return nil, false
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L414: l.active++
    • What: Updates a counter.
    • Why: Maintains an index or tally used by subsequent logic.
    • How: Executes an increment/decrement statement.
  • L415: var once sync.Once
    • What: Declares local names.
    • Why: Introduces variables or types used later in the function.
    • How: Executes a Go declaration statement inside the function body.
  • L416: return func() { once.Do(func() { l.mu.Lock() l.active-- l.mu.Unlock() }) }, true
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).
    • Nested steps:
      • L416: func() { once.Do(func() { l.mu.Lock() l.active-- l.mu.Unlock() }) }
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L417: once.Do(func() { l.mu.Lock() l.active-- l.mu.Unlock() })
            • What: Calls once.Do.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
            • Nested steps:
              • L417: func() { l.mu.Lock() l.active-- l.mu.Unlock() }
                • What: Defines an inline function (closure).
                • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
                • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
                • Nested steps:
                  • L418: l.mu.Lock()
                    • What: Calls l.mu.Lock.
                    • Why: Performs side effects or delegates work to a helper.
                    • How: Executes the expression statement.
                  • L419: l.active--
                    • What: Updates a counter.
                    • Why: Maintains an index or tally used by subsequent logic.
                    • How: Executes an increment/decrement statement.
                  • L420: l.mu.Unlock()
                    • What: Calls l.mu.Unlock.
                    • Why: Performs side effects or delegates work to a helper.
                    • How: Executes the expression statement.

isWebSocketRequest

What: Detects whether an HTTP request is attempting to upgrade to a WebSocket connection.

Why: WebSocket upgrades require special handling (capacity limiting, hijack tracking, idle timeouts).

How: Checks whether the request is attempting an upgrade to websocket via the Upgrade and Connection headers.

pkg/gateway/server/server.go#L425
func isWebSocketRequest(r *http.Request) bool {
if r == nil {
return false
}
if strings.EqualFold(r.Header.Get("Upgrade"), "websocket") {
return true
}
connection := strings.ToLower(r.Header.Get("Connection"))
return strings.Contains(connection, "upgrade") && strings.EqualFold(r.Header.Get("Upgrade"), "websocket")
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L426: if r == nil { return false }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L427: return false
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L429: if strings.EqualFold(r.Header.Get("Upgrade"), "websocket") { return true }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L430: return true
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L432: connection := strings.ToLower(r.Header.Get("Connection"))
    • What: Defines connection.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L433: return strings.Contains(connection, "upgrade") && strings.EqualFold(r.Header.Get("Upgrade"), "websocket")
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

websocketContextFromRequest

What: Extracts websocket limiter context from a request.

Why: The websocket limiter must release capacity when the request completes or when the connection is hijacked/closed.

How: Reads a websocketContext value from the request context and ensures release is non-nil.

pkg/gateway/server/server.go#L443
func websocketContextFromRequest(r *http.Request) (websocketContext, bool) {
if r == nil {
return websocketContext{}, false
}
v, ok := r.Context().Value(websocketContextKey{}).(websocketContext)
if !ok {
return websocketContext{}, false
}
if v.release == nil {
v.release = func() {}
}
return v, true
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L444: if r == nil { return websocketContext{}, false }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L445: return websocketContext{}, false
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L447: v, ok := r.Context().Value(websocketContextKey{}).(websocketContext)
    • What: Defines v, ok.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L448: if !ok { return websocketContext{}, false }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L449: return websocketContext{}, false
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L451: if v.release == nil { v.release = func() {} }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L452: v.release = func() {}
        • What: Assigns v.release.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
        • Nested steps:
          • L452: func() {}
            • What: Defines an inline function (closure).
            • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
            • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
  • L454: return v, true
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

(*Server).buildProtectedHandler

What: Wraps an upstream proxy handler with authentication and scope enforcement.

Why: Trade/task upstreams require JWT authentication with product-specific scopes.

How: Ensures request/trace IDs, authenticates via gatewayauth.Authenticator, checks for required scopes, then forwards the request with routing metadata headers to the proxy.

pkg/gateway/server/server.go#L457
func (s *Server) buildProtectedHandler(product string, requiredScopes []string, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
req, requestID, traceID := ensureRequestIDs(r)
w.Header().Set("X-Request-Id", requestID)
w.Header().Set("X-Trace-Id", traceID)

if s.authenticator == nil {
gatewayproblem.Write(w, http.StatusServiceUnavailable, "Service Unavailable", "Gateway authentication is not configured", traceID, req.URL.Path)
return
}

principal, err := s.authenticator.Authenticate(req)
if err != nil {
s.writeAuthProblem(w, req, err, traceID)
return
}

if !principal.HasAnyScope(requiredScopes) {
gatewayproblem.Write(w, http.StatusForbidden, "Insufficient Scope", fmt.Sprintf("Requires one of scopes: %s", strings.Join(requiredScopes, ", ")), traceID, req.URL.Path)
return
}

req.Header.Set("X-Router-Product", product)
req.Header.Set("X-Request-Id", requestID)
req.Header.Set("X-Trace-Id", traceID)

next.ServeHTTP(w, req)
})
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L458: return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { req, requestID, traceID := ensureRequestIDs(r) w.Header().Set("X-Req…
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).
    • Nested steps:
      • L458: func(w http.ResponseWriter, r *http.Request) { req, requestID, traceID := ensureRequestIDs(r) w.Header().Set("X-Request-Id", requestID) w.H…
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L459: req, requestID, traceID := ensureRequestIDs(r)
            • What: Defines req, requestID, traceID.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L460: w.Header().Set("X-Request-Id", requestID)
            • What: Calls w.Header().Set.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L461: w.Header().Set("X-Trace-Id", traceID)
            • What: Calls w.Header().Set.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L463: if s.authenticator == nil { gatewayproblem.Write(w, http.StatusServiceUnavailable, "Service Unavailable", "Gateway authentication is not co…
            • What: Branches conditionally.
            • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L464: gatewayproblem.Write(w, http.StatusServiceUnavailable, "Service Unavailable", "Gateway authentication is not configured", traceID, req.URL.…
                • What: Calls gatewayproblem.Write.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
              • L465: return
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
          • L468: principal, err := s.authenticator.Authenticate(req)
            • What: Defines principal, err.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L469: if err != nil { s.writeAuthProblem(w, req, err, traceID) return }
            • What: Branches conditionally.
            • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L470: s.writeAuthProblem(w, req, err, traceID)
                • What: Calls s.writeAuthProblem.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
              • L471: return
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
          • L474: if !principal.HasAnyScope(requiredScopes) { gatewayproblem.Write(w, http.StatusForbidden, "Insufficient Scope", fmt.Sprintf("Requires one o…
            • What: Branches conditionally.
            • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L475: gatewayproblem.Write(w, http.StatusForbidden, "Insufficient Scope", fmt.Sprintf("Requires one of scopes: %s", strings.Join(requiredScopes, …
                • What: Calls gatewayproblem.Write.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
              • L476: return
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
          • L479: req.Header.Set("X-Router-Product", product)
            • What: Calls req.Header.Set.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L480: req.Header.Set("X-Request-Id", requestID)
            • What: Calls req.Header.Set.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L481: req.Header.Set("X-Trace-Id", traceID)
            • What: Calls req.Header.Set.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L483: next.ServeHTTP(w, req)
            • What: Calls next.ServeHTTP.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.

(*Server).writeAuthProblem

What: Converts authentication errors into consistent Problem+JSON responses.

Why: Callers need stable error formatting and correct WWW-Authenticate semantics.

How: Special-cases gatewayauth.Error to use its status/title/detail and conditionally sets WWW-Authenticate; otherwise returns a generic 401.

pkg/gateway/server/server.go#L487
func (s *Server) writeAuthProblem(w http.ResponseWriter, r *http.Request, err error, traceID string) {
switch e := err.(type) {
case gatewayauth.Error:
if e.Status == http.StatusUnauthorized {
w.Header().Set("WWW-Authenticate", "Bearer")
}
gatewayproblem.Write(w, e.Status, e.Title, e.Detail, traceID, r.URL.Path)
default:
w.Header().Set("WWW-Authenticate", "Bearer")
gatewayproblem.Write(w, http.StatusUnauthorized, "Authentication Required", err.Error(), traceID, r.URL.Path)
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L488: switch e := err.(type) { case gatewayauth.Error: if e.Status == http.StatusUnauthorized { w.Header().Set("WWW-Authenticate", "Bearer") } ga…
    • What: Selects a branch based on dynamic type.
    • Why: Handles multiple concrete types cleanly.
    • How: Executes a type switch statement.
    • Nested steps:
      • L488: e := err.(type)
        • What: Defines e.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L489: case gatewayauth.Error:
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L490: if e.Status == http.StatusUnauthorized { w.Header().Set("WWW-Authenticate", "Bearer") }
            • What: Branches conditionally.
            • Why: Handles different execution paths based on runtime state.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L491: w.Header().Set("WWW-Authenticate", "Bearer")
                • What: Calls w.Header().Set.
                • Why: Performs side effects or delegates work to a helper.
                • How: Executes the expression statement.
          • L493: gatewayproblem.Write(w, e.Status, e.Title, e.Detail, traceID, r.URL.Path)
            • What: Calls gatewayproblem.Write.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
      • L494: default:
        • What: Selects a switch case.
        • Why: Makes multi-branch control flow explicit and readable.
        • How: Runs this case body when the switch value matches (or when default is selected).
        • Nested steps:
          • L495: w.Header().Set("WWW-Authenticate", "Bearer")
            • What: Calls w.Header().Set.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.
          • L496: gatewayproblem.Write(w, http.StatusUnauthorized, "Authentication Required", err.Error(), traceID, r.URL.Path)
            • What: Calls gatewayproblem.Write.
            • Why: Performs side effects or delegates work to a helper.
            • How: Executes the expression statement.

clientKey

What: Derives the rate-limit key for a request.

Why: Rate limiting needs a stable key; client IP is the default heuristic.

How: Uses clientAddress; falls back to "global" if no address can be resolved.

pkg/gateway/server/server.go#L500
func clientKey(r *http.Request) string {
addr := clientAddress(r)
if addr == "" {
return "global"
}
return addr
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L501: addr := clientAddress(r)
    • What: Defines addr.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L502: if addr == "" { return "global" }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L503: return "global"
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L505: return addr
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

clientAddress

What: Resolves a best-effort client IP address string for logging and rate limiting.

Why: Gateway deployments are commonly behind load balancers; RemoteAddr may reflect a proxy.

How: Uses the first value in X-Forwarded-For when present, otherwise parses RemoteAddr host.

pkg/gateway/server/server.go#L508
func clientAddress(r *http.Request) string {
if r == nil {
return ""
}

if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" {
parts := strings.Split(forwarded, ",")
if len(parts) > 0 {
return strings.TrimSpace(parts[0])
}
}

host, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return strings.TrimSpace(r.RemoteAddr)
}
return host
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L509: if r == nil { return "" }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L510: return ""
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L513: if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" { parts := strings.Split(forwarded, ",") if len(parts) > 0 { return string…
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L513: forwarded := r.Header.Get("X-Forwarded-For")
        • What: Defines forwarded.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L514: parts := strings.Split(forwarded, ",")
        • What: Defines parts.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L515: if len(parts) > 0 { return strings.TrimSpace(parts[0]) }
        • What: Branches conditionally.
        • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L516: return strings.TrimSpace(parts[0])
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).
  • L520: host, _, err := net.SplitHostPort(r.RemoteAddr)
    • What: Defines host, _, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L521: if err != nil { return strings.TrimSpace(r.RemoteAddr) }
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L522: return strings.TrimSpace(r.RemoteAddr)
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L524: return host
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).

buildCORS

What: Constructs a CORS policy object from configured allowed origins.

Why: Browser clients require explicit cross-origin policy; CORS needs to be environment-configurable.

How: Treats empty origins as allow-all, supports * to force allow-all, otherwise allows only exact origin matches and configures allowed methods/headers.

pkg/gateway/server/server.go#L527
func buildCORS(origins []string) *cors.Cors {
allowAll := len(origins) == 0

allowed := make(map[string]struct{})
for _, origin := range origins {
o := strings.TrimSpace(origin)
if o == "" {
continue
}
if o == "*" {
allowAll = true
allowed = nil
break
}
allowed[o] = struct{}{}
}

return cors.New(cors.Options{
AllowedMethods: []string{http.MethodGet, http.MethodHead, http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete, http.MethodOptions},
AllowedHeaders: []string{"*"},
ExposedHeaders: []string{"X-Request-Id", "X-Trace-Id"},
OptionsSuccessStatus: http.StatusNoContent,
AllowOriginRequestFunc: func(_ *http.Request, origin string) bool {
if origin == "" {
return true
}
if allowAll {
return true
}
if allowed == nil {
return true
}
_, ok := allowed[origin]
return ok
},
})
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L528: allowAll := len(origins) == 0
    • What: Defines allowAll.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L530: allowed := make(map[string]struct{})
    • What: Defines allowed.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L531: for _, origin := range origins { o := strings.TrimSpace(origin) if o == "" { continue } if o == "*" { allowAll = true allowed = nil break }…
    • What: Iterates over a collection.
    • Why: Processes multiple elements with the same logic.
    • How: Executes a for ... range loop.
    • Nested steps:
      • L532: o := strings.TrimSpace(origin)
        • What: Defines o.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L533: if o == "" { continue }
        • What: Branches conditionally.
        • Why: Handles different execution paths based on runtime state.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L534: continue
            • What: Executes a statement.
            • Why: Advances the function logic.
            • How: Runs this statement as part of the function body.
      • L536: if o == "*" { allowAll = true allowed = nil break }
        • What: Branches conditionally.
        • Why: Handles different execution paths based on runtime state.
        • How: Evaluates the condition and executes the matching branch.
        • Nested steps:
          • L537: allowAll = true
            • What: Assigns allowAll.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L538: allowed = nil
            • What: Assigns allowed.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L539: break
            • What: Executes a statement.
            • Why: Advances the function logic.
            • How: Runs this statement as part of the function body.
      • L541: allowed[o] = struct{}{}
        • What: Assigns allowed[o].
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L544: return cors.New(cors.Options{ AllowedMethods: []string{http.MethodGet, http.MethodHead, http.MethodPost, http.MethodPut, http.MethodPatch, …
    • What: Returns from the current function.
    • Why: Ends the current execution path and hands control back to the caller.
    • How: Executes a return statement (possibly returning values).
    • Nested steps:
      • L549: func(_ *http.Request, origin string) bool { if origin == "" { return true } if allowAll { return true } if allowed == nil { return true } _…
        • What: Defines an inline function (closure).
        • Why: Encapsulates callback logic and may capture variables from the surrounding scope.
        • How: Declares a func literal and uses it as a value (for example, as an HTTP handler or callback).
        • Nested steps:
          • L550: if origin == "" { return true }
            • What: Branches conditionally.
            • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L551: return true
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
          • L553: if allowAll { return true }
            • What: Branches conditionally.
            • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L554: return true
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
          • L556: if allowed == nil { return true }
            • What: Branches conditionally.
            • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
            • How: Evaluates the condition and executes the matching branch.
            • Nested steps:
              • L557: return true
                • What: Returns from the current function.
                • Why: Ends the current execution path and hands control back to the caller.
                • How: Executes a return statement (possibly returning values).
          • L559: _, ok := allowed[origin]
            • What: Defines _, ok.
            • Why: Keeps intermediate state available for later steps in the function.
            • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
          • L560: return ok
            • What: Returns from the current function.
            • Why: Ends the current execution path and hands control back to the caller.
            • How: Executes a return statement (possibly returning values).

(*Server).handleHealth

What: Implements GET /health and returns basic process health + metadata.

Why: Provides a lightweight liveness endpoint for load balancers and orchestration.

How: Returns JSON with status, uptime, timestamp, and optional version; always 200 unless encoding fails.

pkg/gateway/server/server.go#L565
func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
_, requestID, _ := ensureRequestIDs(r)
w.Header().Set("Content-Type", "application/json")
w.Header().Set("X-Request-Id", requestID)

response := struct {
Status string `json:"status"`
Uptime float64 `json:"uptime"`
Timestamp string `json:"timestamp"`
Version string `json:"version,omitempty"`
}{
Status: "ok",
Uptime: time.Since(s.bootTime).Seconds(),
Timestamp: time.Now().UTC().Format(time.RFC3339),
Version: s.cfg.Version,
}

w.WriteHeader(http.StatusOK)
_ = json.NewEncoder(w).Encode(response)
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L566: _, requestID, _ := ensureRequestIDs(r)
    • What: Defines _, requestID, _.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L567: w.Header().Set("Content-Type", "application/json")
    • What: Calls w.Header().Set.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L568: w.Header().Set("X-Request-Id", requestID)
    • What: Calls w.Header().Set.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L570: response := struct { Status string `json:"status"` Uptime float64 `json:"uptime"` Timestamp string `json:"timestamp"` Version string `json:…
    • What: Defines response.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L582: w.WriteHeader(http.StatusOK)
    • What: Calls w.WriteHeader.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L583: _ = json.NewEncoder(w).Encode(response)
    • What: Assigns _.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.

(*Server).handleReadiness

What: Implements GET /readyz and GET /readiness by probing upstreams.

Why: Readiness should reflect upstream reachability so rollouts don't send traffic to an unusable gateway.

How: Calls healthChecker.Readiness, returns 200 when ready and 503 otherwise, and includes upstream results plus request/trace IDs in JSON.

pkg/gateway/server/server.go#L586
func (s *Server) handleReadiness(w http.ResponseWriter, r *http.Request) {
var requestID, traceID string
r, requestID, traceID = ensureRequestIDs(r)
w.Header().Set("Content-Type", "application/json")
w.Header().Set("X-Request-Id", requestID)

report := health.Report{Status: "ready", CheckedAt: time.Now().UTC()}
if s.healthChecker != nil {
report = s.healthChecker.Readiness(r.Context())
}

statusCode := http.StatusOK
if report.Status != "ready" {
statusCode = http.StatusServiceUnavailable
}

response := struct {
Status string `json:"status"`
CheckedAt time.Time `json:"checkedAt"`
Upstreams []health.UpstreamReport `json:"upstreams"`
RequestID string `json:"requestId,omitempty"`
TraceID string `json:"traceId,omitempty"`
}{
Status: report.Status,
CheckedAt: report.CheckedAt,
Upstreams: report.Upstreams,
RequestID: requestID,
TraceID: traceID,
}

w.WriteHeader(statusCode)
_ = json.NewEncoder(w).Encode(response)
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L587: var requestID, traceID string
    • What: Declares local names.
    • Why: Introduces variables or types used later in the function.
    • How: Executes a Go declaration statement inside the function body.
  • L588: r, requestID, traceID = ensureRequestIDs(r)
    • What: Assigns r, requestID, traceID.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L589: w.Header().Set("Content-Type", "application/json")
    • What: Calls w.Header().Set.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L590: w.Header().Set("X-Request-Id", requestID)
    • What: Calls w.Header().Set.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L592: report := health.Report{Status: "ready", CheckedAt: time.Now().UTC()}
    • What: Defines report.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L593: if s.healthChecker != nil { report = s.healthChecker.Readiness(r.Context()) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L594: report = s.healthChecker.Readiness(r.Context())
        • What: Assigns report.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L597: statusCode := http.StatusOK
    • What: Defines statusCode.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L598: if report.Status != "ready" { statusCode = http.StatusServiceUnavailable }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L599: statusCode = http.StatusServiceUnavailable
        • What: Assigns statusCode.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L602: response := struct { Status string `json:"status"` CheckedAt time.Time `json:"checkedAt"` Upstreams []health.UpstreamReport `json:"upstream…
    • What: Defines response.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L616: w.WriteHeader(statusCode)
    • What: Calls w.WriteHeader.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L617: _ = json.NewEncoder(w).Encode(response)
    • What: Assigns _.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.

(*Server).handleOpenAPI

What: Implements GET /openapi.json using the configured OpenAPI provider.

Why: Exposes the merged API contract for clients and tooling.

How: Calls openapiProvider.Document(ctx), returns Problem+JSON on error, otherwise writes the raw JSON bytes.

pkg/gateway/server/server.go#L620
func (s *Server) handleOpenAPI(w http.ResponseWriter, r *http.Request) {
if s.openapiProvider == nil {
gatewayproblem.Write(w, http.StatusServiceUnavailable, "OpenAPI Unavailable", "OpenAPI provider not configured", traceIDFromContext(r.Context()), r.URL.Path)
return
}

data, err := s.openapiProvider.Document(r.Context())
if err != nil {
traceID := traceIDFromContext(r.Context())
gatewayproblem.Write(w, http.StatusServiceUnavailable, "OpenAPI Unavailable", err.Error(), traceID, r.URL.Path)
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
if _, err := w.Write(data); err != nil {
s.logger.Warnw("failed to write openapi response", "error", err)
}
}

Walkthrough

The list below documents the statements inside the function body, including nested blocks and inline closures.

  • L621: if s.openapiProvider == nil { gatewayproblem.Write(w, http.StatusServiceUnavailable, "OpenAPI Unavailable", "OpenAPI provider not configure…
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L622: gatewayproblem.Write(w, http.StatusServiceUnavailable, "OpenAPI Unavailable", "OpenAPI provider not configured", traceIDFromContext(r.Conte…
        • What: Calls gatewayproblem.Write.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L623: return
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L626: data, err := s.openapiProvider.Document(r.Context())
    • What: Defines data, err.
    • Why: Keeps intermediate state available for later steps in the function.
    • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
  • L627: if err != nil { traceID := traceIDFromContext(r.Context()) gatewayproblem.Write(w, http.StatusServiceUnavailable, "OpenAPI Unavailable", er…
    • What: Branches conditionally.
    • Why: Short-circuits early when a precondition is not met or an error/edge case is detected.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L628: traceID := traceIDFromContext(r.Context())
        • What: Defines traceID.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L629: gatewayproblem.Write(w, http.StatusServiceUnavailable, "OpenAPI Unavailable", err.Error(), traceID, r.URL.Path)
        • What: Calls gatewayproblem.Write.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.
      • L630: return
        • What: Returns from the current function.
        • Why: Ends the current execution path and hands control back to the caller.
        • How: Executes a return statement (possibly returning values).
  • L633: w.Header().Set("Content-Type", "application/json")
    • What: Calls w.Header().Set.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L634: w.WriteHeader(http.StatusOK)
    • What: Calls w.WriteHeader.
    • Why: Performs side effects or delegates work to a helper.
    • How: Executes the expression statement.
  • L635: if _, err := w.Write(data); err != nil { s.logger.Warnw("failed to write openapi response", "error", err) }
    • What: Branches conditionally.
    • Why: Handles different execution paths based on runtime state.
    • How: Evaluates the condition and executes the matching branch.
    • Nested steps:
      • L635: _, err := w.Write(data)
        • What: Defines _, err.
        • Why: Keeps intermediate state available for later steps in the function.
        • How: Evaluates the right-hand side expressions and stores results in the left-hand variables.
      • L636: s.logger.Warnw("failed to write openapi response", "error", err)
        • What: Calls s.logger.Warnw.
        • Why: Performs side effects or delegates work to a helper.
        • How: Executes the expression statement.

Start Here

Architecture

Guides

Reference

Neighboring source