fix automatic json response handling

This commit is contained in:
Sky Johnson 2025-06-04 11:11:21 -05:00
parent 769a8dd2ce
commit c2be77bf6a

View File

@ -11,6 +11,7 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv" "strconv"
"strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -589,6 +590,15 @@ func ApplyResponse(resp *Response, ctx *fasthttp.RequestCtx) {
return return
} }
// Check if Content-Type was manually set
contentTypeSet := false
for name := range resp.Headers {
if strings.ToLower(name) == "content-type" {
contentTypeSet = true
break
}
}
// Get a buffer from the pool // Get a buffer from the pool
buf := bytebufferpool.Get() buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf) defer bytebufferpool.Put(buf)
@ -596,23 +606,50 @@ func ApplyResponse(resp *Response, ctx *fasthttp.RequestCtx) {
// Set body based on type // Set body based on type
switch body := resp.Body.(type) { switch body := resp.Body.(type) {
case string: case string:
if !contentTypeSet {
ctx.Response.Header.SetContentType("text/plain; charset=utf-8")
}
ctx.SetBodyString(body) ctx.SetBodyString(body)
case []byte: case []byte:
if !contentTypeSet {
ctx.Response.Header.SetContentType("text/plain; charset=utf-8")
}
ctx.SetBody(body) ctx.SetBody(body)
case map[string]any, []any, []float64, []string, []int: case map[string]any, map[any]any, []any, []float64, []string, []int, []map[string]any:
// Marshal JSON // Marshal JSON
if err := json.NewEncoder(buf).Encode(body); err == nil { if err := json.NewEncoder(buf).Encode(body); err == nil {
// Set content type if not already set if !contentTypeSet {
if len(ctx.Response.Header.ContentType()) == 0 {
ctx.Response.Header.SetContentType("application/json") ctx.Response.Header.SetContentType("application/json")
} }
ctx.SetBody(buf.Bytes()) ctx.SetBody(buf.Bytes())
} else { } else {
// Fallback // Fallback to string representation
if !contentTypeSet {
ctx.Response.Header.SetContentType("text/plain; charset=utf-8")
}
ctx.SetBodyString(fmt.Sprintf("%v", body)) ctx.SetBodyString(fmt.Sprintf("%v", body))
} }
default: default:
// Default to string representation // Check if it's any other map or slice type
ctx.SetBodyString(fmt.Sprintf("%v", body)) typeStr := fmt.Sprintf("%T", body)
if typeStr[0] == '[' || (len(typeStr) > 3 && typeStr[:3] == "map") {
if err := json.NewEncoder(buf).Encode(body); err == nil {
if !contentTypeSet {
ctx.Response.Header.SetContentType("application/json")
}
ctx.SetBody(buf.Bytes())
} else {
if !contentTypeSet {
ctx.Response.Header.SetContentType("text/plain; charset=utf-8")
}
ctx.SetBodyString(fmt.Sprintf("%v", body))
}
} else {
// Default to string representation
if !contentTypeSet {
ctx.Response.Header.SetContentType("text/plain; charset=utf-8")
}
ctx.SetBodyString(fmt.Sprintf("%v", body))
}
} }
} }