diff --git a/pkg/client/restclient/client.go b/pkg/client/restclient/client.go index 782797ad767c2..bf813d052a0c7 100644 --- a/pkg/client/restclient/client.go +++ b/pkg/client/restclient/client.go @@ -69,6 +69,7 @@ type Serializers struct { Decoder runtime.Decoder StreamingSerializer runtime.Serializer Framer runtime.Framer + RenegotiatedDecoder func(contentType string, params map[string]string) (runtime.Decoder, error) } // NewRESTClient creates a new RESTClient. This client performs generic REST functions @@ -156,6 +157,13 @@ func createSerializers(config ContentConfig) (*Serializers, error) { Decoder: negotiated.DecoderToVersion(info.Serializer, internalGV), StreamingSerializer: streamInfo.Serializer, Framer: streamInfo.Framer, + RenegotiatedDecoder: func(contentType string, params map[string]string) (runtime.Decoder, error) { + renegotiated, ok := negotiated.SerializerForMediaType(contentType, params) + if !ok { + return nil, fmt.Errorf("serializer for %s not registered", contentType) + } + return negotiated.DecoderToVersion(renegotiated.Serializer, internalGV), nil + }, }, nil } diff --git a/pkg/client/restclient/request.go b/pkg/client/restclient/request.go index e5d3511d1bf39..7050eab9a9849 100644 --- a/pkg/client/restclient/request.go +++ b/pkg/client/restclient/request.go @@ -910,12 +910,30 @@ func (r *Request) transformResponse(resp *http.Response, req *http.Request) Resu return Result{err: errors.FromObject(status)} } - // TODO: Check ContentType. + contentType := resp.Header.Get("Content-Type") + var decoder runtime.Decoder + if contentType == r.content.ContentType { + decoder = r.serializers.Decoder + } else { + mediaType, params, err := mime.ParseMediaType(contentType) + if err != nil { + return Result{err: errors.NewInternalError(err)} + } + decoder, err = r.serializers.RenegotiatedDecoder(mediaType, params) + if err != nil { + return Result{ + body: body, + contentType: contentType, + statusCode: resp.StatusCode, + } + } + } + return Result{ body: body, - contentType: resp.Header.Get("Content-Type"), + contentType: contentType, statusCode: resp.StatusCode, - decoder: r.serializers.Decoder, + decoder: decoder, } } @@ -1021,6 +1039,9 @@ func (r Result) Get() (runtime.Object, error) { if r.err != nil { return nil, r.err } + if r.decoder == nil { + return nil, fmt.Errorf("serializer for %s doesn't exist", r.contentType) + } return runtime.Decode(r.decoder, r.body) } @@ -1036,6 +1057,9 @@ func (r Result) Into(obj runtime.Object) error { if r.err != nil { return r.err } + if r.decoder == nil { + return fmt.Errorf("serializer for %s doesn't exist", r.contentType) + } return runtime.DecodeInto(r.decoder, r.body, obj) }