-
Notifications
You must be signed in to change notification settings - Fork 20
[duplicate-code] Duplicate Code Pattern: Manual JSON response writing bypassing httputil.WriteJSONResponse in proxy/handler.go #3312
Description
Part of duplicate code analysis: #3309
Summary
internal/proxy/handler.go contains two locations where JSON HTTP responses are written by manually setting the Content-Type header, calling w.WriteHeader, and then w.Write. The project already provides httputil.WriteJSONResponse (in internal/httputil/httputil.go) that encapsulates exactly this 3-line pattern, but these two sites bypass it.
Duplication Details
Pattern: Manual Content-Type: application/json + WriteHeader + Write instead of httputil.WriteJSONResponse
- Severity: Low
- Occurrences: 2 (≈6 lines)
- Locations:
internal/proxy/handler.goline 328–331 (inside DIFC-filtered GraphQL response path)internal/proxy/handler.goline 365–367 (insidewriteEmptyResponse)
- Code Sample:
// handler.go:328-331
copyResponseHeaders(w, resp)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(resp.StatusCode)
w.Write(filteredJSON)
// handler.go:364-367
func (h *proxyHandler) writeEmptyResponse(w http.ResponseWriter, resp *http.Response, originalData interface{}) {
copyResponseHeaders(w, resp)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(resp.StatusCode)
...
w.Write([]byte(empty))
}- Existing helper (
internal/httputil/httputil.go):
func WriteJSONResponse(w http.ResponseWriter, statusCode int, body interface{}) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(statusCode)
json.NewEncoder(w).Encode(body)
}Note: httputil.WriteJSONResponse is already used correctly elsewhere in the same file (lines 28, 51, 83).
Impact Analysis
- Maintainability: If the JSON response format or headers change (e.g. adding
X-Content-Type-Options), the two manual sites would be missed. - Bug Risk:
httputil.WriteJSONResponseusesjson.NewEncoder(w).Encode(body)which adds a trailing newline and handles encoding; the manual sites use raww.Write([]byte)which skips encoding safety. - Consistency: Inconsistent use of the helper within the same file.
Refactoring Recommendations
-
Site 1 (
handler.goline 328–331): Replace the manual 3-line block with a call tohttputil.WriteJSONResponse(w, resp.StatusCode, json.RawMessage(filteredJSON))aftercopyResponseHeaders. Note:copyResponseHeadersmust still be called first to preserve upstream response headers. -
Site 2 (
writeEmptyResponse): The empty-body case writes a raw string ("[]","{}",{"data":null}), sohttputil.WriteJSONResponsefits directly:httputil.WriteJSONResponse(w, resp.StatusCode, json.RawMessage(empty)).Estimated effort: 30 minutes. Purely mechanical substitution with no behavioural change.
Implementation Checklist
- Replace manual JSON response writes at
handler.go:328–331andhandler.go:364–383 - Verify
copyResponseHeadersis still called before the helper (header order matters) - Run
make testto confirm proxy handler tests pass - Run
make agent-finished
Parent Issue
See parent analysis report: #3309
Related to #3309
Generated by Duplicate Code Detector · ● 2.2M · ◷
- expires on Apr 14, 2026, 6:05 AM UTC