Skip to content

[duplicate-code] Duplicate Code Pattern: Common HTTP mux setup duplicated between routed.go and transport.go #1159

@github-actions

Description

@github-actions

Part of duplicate code analysis: #1158

Summary

CreateHTTPServerForRoutedMode (routed.go) and CreateHTTPServerForMCP (transport.go) both register identical sets of shared HTTP routes: two OAuth discovery endpoints, one health check endpoint, and one close endpoint with auth middleware. This ~14-line block is copy-pasted between the two functions.

Duplication Details

Pattern: Identical shared route registration in two HTTP server creation functions

  • Severity: Medium
  • Occurrences: 2 (one per server creation function)
  • Locations:
    • internal/server/routed.go (lines 85–89, 161–176) — OAuth, health, close setup
    • internal/server/transport.go (lines 74–78, 134–144) — identical OAuth, health, close setup

Duplicated block in routed.go:

// OAuth discovery endpoints
mux.Handle("/.well-known/oauth-authorization-server", withResponseLogging(handleOAuthDiscovery()))
mux.Handle("/mcp/.well-known/oauth-authorization-server", withResponseLogging(handleOAuthDiscovery()))

// Health check (spec 8.1.1)
healthHandler := HandleHealth(unifiedServer)
mux.Handle("/health", withResponseLogging(healthHandler))

// Close endpoint for graceful shutdown (spec 5.1.3)
closeHandler := handleClose(unifiedServer)
finalCloseHandler := closeHandler
if apiKey != "" {
    finalCloseHandler = authMiddleware(apiKey, closeHandler.ServeHTTP)
}
mux.Handle("/close", withResponseLogging(finalCloseHandler))

Duplicated block in transport.go (structurally identical):

// OAuth discovery endpoints
mux.Handle("/.well-known/oauth-authorization-server", withResponseLogging(handleOAuthDiscovery()))
mux.Handle("/mcp/.well-known/oauth-authorization-server", withResponseLogging(handleOAuthDiscovery()))

// Health check (spec 8.1.1)
healthHandler := HandleHealth(unifiedServer)
mux.Handle("/health", withResponseLogging(healthHandler))

// Close endpoint for graceful shutdown (spec 5.1.3)
closeHandler := handleClose(unifiedServer)
finalCloseHandler := applyAuthIfConfigured(apiKey, closeHandler.ServeHTTP)
mux.Handle("/close", withResponseLogging(finalCloseHandler))

Impact Analysis

  • Maintainability: Adding a new shared endpoint (e.g., /metrics, /ready) requires changes in two places.
  • Bug Risk: The close endpoint registration already differs slightly: routed.go uses the inline auth conditional while transport.go uses applyAuthIfConfigured. This inconsistency could introduce divergence in future changes.
  • Code Bloat: ~14 duplicated lines across two functions.

Refactoring Recommendations

  1. Extract registerCommonEndpoints helper function
    • Create a new function in internal/server/ (e.g., handlers.go or a new mux_helpers.go):
      func registerCommonEndpoints(mux *http.ServeMux, unifiedServer *UnifiedServer, apiKey string) {
          mux.Handle("/.well-known/oauth-authorization-server", withResponseLogging(handleOAuthDiscovery()))
          mux.Handle("/mcp/.well-known/oauth-authorization-server", withResponseLogging(handleOAuthDiscovery()))
          mux.Handle("/health", withResponseLogging(HandleHealth(unifiedServer)))
          closeHandler := handleClose(unifiedServer)
          mux.Handle("/close", withResponseLogging(applyAuthIfConfigured(apiKey, closeHandler.ServeHTTP)))
      }
    • Call it from both CreateHTTPServerForRoutedMode and CreateHTTPServerForMCP
    • Estimated effort: 1–2 hours
    • Benefits: Single point of change for all shared endpoints, consistent auth handling

Implementation Checklist

  • Review duplication findings
  • Extract registerCommonEndpoints (or similar) helper function
  • Update routed.go and transport.go to use the new helper
  • Update tests to cover the new helper
  • Verify no functionality broken (make test)

Parent Issue

See parent analysis report: #1158
Related to #1158

Generated by Duplicate Code Detector

  • expires on Feb 27, 2026, 2:58 AM UTC

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions