From b1b255f90a52eb0e81be44ccdee37fc13bdb2b28 Mon Sep 17 00:00:00 2001 From: Clayton Coleman Date: Thu, 11 Dec 2014 20:25:07 -0500 Subject: [PATCH] Prevent infinite loop in apiserver errorJSON --- pkg/apiserver/apiserver.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index cf4738941b7..bb61e648d3a 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -19,6 +19,7 @@ package apiserver import ( "bytes" "encoding/json" + "fmt" "io/ioutil" "net/http" "path" @@ -283,16 +284,14 @@ func APIVersionHandler(versions ...string) restful.RouteFunction { func writeJSON(statusCode int, codec runtime.Codec, object runtime.Object, w http.ResponseWriter) { output, err := codec.Encode(object) if err != nil { - // Note: If codec is broken, this results in an infinite recursion - errorJSON(err, codec, w) + errorJSONFatal(err, codec, w) return } // PR #2243: Pretty-print JSON by default. formatted := &bytes.Buffer{} err = json.Indent(formatted, output, "", " ") if err != nil { - // Note: If codec is broken, this results in an infinite recursion - errorJSON(err, codec, w) + errorJSONFatal(err, codec, w) return } w.Header().Set("Content-Type", "application/json") @@ -306,6 +305,20 @@ func errorJSON(err error, codec runtime.Codec, w http.ResponseWriter) { writeJSON(status.Code, codec, status, w) } +// errorJSONFatal renders an error to the response, and if codec fails will render plaintext +func errorJSONFatal(err error, codec runtime.Codec, w http.ResponseWriter) { + status := errToAPIStatus(err) + output, err := codec.Encode(status) + if err != nil { + w.WriteHeader(status.Code) + fmt.Fprintf(w, "%s: %s", status.Reason, status.Message) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status.Code) + w.Write(output) +} + // writeRawJSON writes a non-API object in JSON. func writeRawJSON(statusCode int, object interface{}, w http.ResponseWriter) { // PR #2243: Pretty-print JSON by default.