Skip to content

[duplicate-code] Duplicate Code Pattern: HTTP Response Writer Wrappers #377

@github-actions

Description

@github-actions

🔍 Duplicate Code Pattern: HTTP Response Writer Wrappers

Part of duplicate code analysis: #375

Summary

Two nearly identical HTTP response writer wrapper implementations exist in the server package, differing only in field type (bytes.Buffer vs []byte). This duplication was introduced as part of the SDK logging changes in PR #372.

Duplication Details

Pattern: Response Writer Wrapper for Capturing Output

  • Severity: Medium
  • Occurrences: 2 instances
  • Locations:
    • internal/server/sdk_logging.go (lines 40-54) - sdkLoggingResponseWriter
    • internal/server/transport.go (lines 52-66) - loggingResponseWriter

Code Comparison:

sdk_logging.go (uses bytes.Buffer):

type sdkLoggingResponseWriter struct {
    http.ResponseWriter
    body       bytes.Buffer
    statusCode int
}

func (w *sdkLoggingResponseWriter) WriteHeader(statusCode int) {
    w.statusCode = statusCode
    w.ResponseWriter.WriteHeader(statusCode)
}

func (w *sdkLoggingResponseWriter) Write(b []byte) (int, error) {
    w.body.Write(b)
    return w.ResponseWriter.Write(b)
}

transport.go (uses []byte):

type loggingResponseWriter struct {
    http.ResponseWriter
    body       []byte
    statusCode int
}

func (w *loggingResponseWriter) WriteHeader(statusCode int) {
    w.statusCode = statusCode
    w.ResponseWriter.WriteHeader(statusCode)
}

func (w *loggingResponseWriter) Write(b []byte) (int, error) {
    w.body = append(w.body, b...)
    return w.ResponseWriter.Write(b)
}

Key Difference: Only the body storage type differs (bytes.Buffer vs []byte with append)

Impact Analysis

  • Maintainability: Changes to response capture logic need duplication across both types
  • Bug Risk: Low - implementations are simple, but inconsistency could cause confusion
  • Code Bloat: ~15 lines duplicated
  • Testing: Requires separate tests for identical functionality

Refactoring Recommendations

1. Extract to Shared Middleware Utility (Recommended)

  • Create internal/server/middleware.go with unified response writer:
    // responseCapturingWriter wraps http.ResponseWriter to capture response body
    type responseCapturingWriter struct {
        http.ResponseWriter
        body       *bytes.Buffer
        statusCode int
    }
  • Location: internal/server/middleware.go (new file)
  • Estimated effort: 1 hour
  • Benefits:
    • Single implementation for all logging needs
    • Consistent behavior across different logging contexts
    • Easier to enhance (e.g., add size limits, compression)

2. Standardize on bytes.Buffer

  • Use bytes.Buffer in both locations (more efficient for large responses)
  • Update transport.go to match sdk_logging.go pattern
  • Estimated effort: 15 minutes
  • Benefits:
    • Quick fix
    • Better memory efficiency with Buffer API

3. Wrapper Factory Function

  • Create factory: func newLoggingResponseWriter(w http.ResponseWriter) *loggingResponseWriter
  • Consolidate initialization logic
  • Estimated effort: 30 minutes

Implementation Checklist

  • Create internal/server/middleware.go with shared response writer
  • Add unit tests for response writer wrapper
  • Update sdk_logging.go to use shared implementation
  • Update transport.go to use shared implementation
  • Remove duplicate type definitions
  • Verify all logging functionality still works correctly
  • Consider adding response size limits or streaming support

Parent Issue

See parent analysis report: #375
Related to #375

AI generated by Duplicate Code Detector

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