Part of duplicate code analysis: #1283
Summary
The three-step middleware wrapping chain (WithSDKLogging → rejectIfShutdown → applyAuthIfConfigured) and the final http.Server construction are duplicated verbatim between CreateHTTPServerForMCP (transport.go) and CreateHTTPServerForRoutedMode (routed.go), along with identical comments.
Duplication Details
Pattern: Middleware chain + http.Server construction
- Severity: Low
- Occurrences: 2 (one per HTTP server factory function)
- Locations:
internal/server/transport.go (lines 118–135)
internal/server/routed.go (lines 140–162, inside per-backend loop)
transport.go:
// Wrap SDK handler with detailed logging for JSON-RPC translation debugging
loggedHandler := WithSDKLogging(streamableHandler, "unified")
// Apply shutdown check middleware (spec 5.1.3)
// This must come before auth to ensure shutdown takes precedence
shutdownHandler := rejectIfShutdown(unifiedServer, loggedHandler, "server:transport")
// Apply auth middleware if API key is configured (spec 7.1)
finalHandler := applyAuthIfConfigured(apiKey, shutdownHandler.ServeHTTP)
mux.Handle("/mcp/", finalHandler)
mux.Handle("/mcp", finalHandler)
return &http.Server{Addr: addr, Handler: mux}
routed.go (inside per-backend loop, then after):
loggedHandler := WithSDKLogging(routeHandler, "routed:"+backendID)
shutdownHandler := rejectIfShutdown(unifiedServer, loggedHandler, "server:routed")
finalHandler := applyAuthIfConfigured(apiKey, shutdownHandler.ServeHTTP)
mux.Handle(route+"/", finalHandler)
mux.Handle(route, finalHandler)
// ... (outside loop)
return &http.Server{Addr: addr, Handler: mux}
Impact Analysis
- Maintainability: Adding a new middleware layer (e.g., rate limiting, tracing) requires changes in both files. The spec references in comments (5.1.3, 7.1) would also need to be kept in sync.
- Bug Risk: Low, since the middleware order is mechanically enforced, but adding middleware only in one place is a realistic mistake.
- Code Bloat: Minor (~6 lines duplicated).
Refactoring Recommendations
-
Extract a wrapWithMiddleware helper in transport.go or http_helpers.go:
// wrapWithMiddleware applies the standard middleware stack to an SDK handler.
// Order: SDK logging → shutdown check (spec 5.1.3) → auth (spec 7.1)
func wrapWithMiddleware(handler http.Handler, logTag string, unifiedServer *UnifiedServer, apiKey string) http.HandlerFunc {
loggedHandler := WithSDKLogging(handler, logTag)
shutdownHandler := rejectIfShutdown(unifiedServer, loggedHandler, "server:"+logTag)
return applyAuthIfConfigured(apiKey, shutdownHandler.ServeHTTP)
}
-
Optionally extract buildHTTPServer:
func buildHTTPServer(addr string, mux *http.ServeMux) *http.Server {
return &http.Server{Addr: addr, Handler: mux}
}
-
Estimated effort: ~20 minutes
-
Benefits: Middleware order documented and enforced in one place; easier to add new middleware globally
Implementation Checklist
Parent Issue
See parent analysis report: #1283
Related to #1283
Generated by Duplicate Code Detector
Part of duplicate code analysis: #1283
Summary
The three-step middleware wrapping chain (
WithSDKLogging→rejectIfShutdown→applyAuthIfConfigured) and the finalhttp.Serverconstruction are duplicated verbatim betweenCreateHTTPServerForMCP(transport.go) andCreateHTTPServerForRoutedMode(routed.go), along with identical comments.Duplication Details
Pattern: Middleware chain + http.Server construction
internal/server/transport.go(lines 118–135)internal/server/routed.go(lines 140–162, inside per-backend loop)transport.go:routed.go(inside per-backend loop, then after):Impact Analysis
Refactoring Recommendations
Extract a
wrapWithMiddlewarehelper intransport.goorhttp_helpers.go:Optionally extract
buildHTTPServer:Estimated effort: ~20 minutes
Benefits: Middleware order documented and enforced in one place; easier to add new middleware globally
Implementation Checklist
wrapWithMiddlewarehelpertransport.goandrouted.goto use the helperParent Issue
See parent analysis report: #1283
Related to #1283