Skip to content

[duplicate-code] Duplicate Code Pattern: HTTP Client Transport Clone in internal/mcp/http_transport_client.go #9100

Description

@github-actions

Summary

Part of duplicate code analysis: #9098

Two functions in internal/mcp/http_transport_client.go share an identical 6-line core for cloning an http.Client and assigning a new transport. This core could be extracted into a private helper.

Duplication Details

Pattern: http.Client shallow clone + transport assignment

  • Severity: Medium

  • Occurrences: 2 instances (6 lines each)

  • Locations:

    • internal/mcp/http_transport_client.go lines ~57–63 (inside buildHTTPClientWithHeaders)
    • internal/mcp/http_transport_client.go lines ~93–103 (inside buildHTTPClientWithOIDC)
  • Code Sample:

// In buildHTTPClientWithHeaders (lines ~57–63):
base := baseClient.Transport
if base == nil {
    base = http.DefaultTransport
}
clone := *baseClient
clone.Transport = &headerInjectingRoundTripper{base: base, headers: headers}
return &clone

// In buildHTTPClientWithOIDC (lines ~93–103):
base := baseClient.Transport
if base == nil {
    base = http.DefaultTransport
}
clone := *baseClient
clone.Transport = &oidcRoundTripper{base: base, provider: provider, audience: audience}
return &clone

The only difference is the concrete RoundTripper type assigned to clone.Transport.

Impact Analysis

  • Maintainability: Any change to client cloning behavior (e.g., copying additional fields, adding timeout overrides) must be applied to both functions
  • Bug Risk: Low but present — inconsistent fixes if the nil-guard logic changes
  • Code Bloat: Minor (~6 lines), but a clear extraction opportunity

Refactoring Recommendations

  1. Extract cloneClientWithTransport helper:
    // cloneClientWithTransport returns a shallow clone of baseClient
    // with Transport replaced by newTransport.
    func cloneClientWithTransport(baseClient *http.Client, newTransport http.RoundTripper) *http.Client {
        base := baseClient.Transport
        if base == nil {
            base = http.DefaultTransport
        }
        _ = base // newTransport already has base captured by caller
        clone := *baseClient
        clone.Transport = newTransport
        return &clone
    }
    Then callers construct the RoundTripper themselves and pass it in:
    func buildHTTPClientWithHeaders(baseClient *http.Client, headers map[string]string) *http.Client {
        if len(headers) == 0 { return baseClient }
        base := baseClient.Transport
        if base == nil { base = http.DefaultTransport }
        return cloneClientWithTransport(baseClient, &headerInjectingRoundTripper{base: base, headers: headers})
    }
    Estimated effort: 30 minutes.

Implementation Checklist

  • Extract cloneClientWithTransport helper in http_transport_client.go
  • Update buildHTTPClientWithHeaders to use it
  • Update buildHTTPClientWithOIDC to use it
  • Run make test to verify no behavioral changes

Parent Issue

See parent analysis report: #9098
Related to #9098

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

Generated by Duplicate Code Detector · 81.3 AIC · ⊞ 7.7K ·

  • expires on Jul 18, 2026, 3:39 AM UTC

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions