From efd88c56763dd8668fb29333e56f8f710463fcf9 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Tue, 25 Jul 2017 17:38:18 +0100 Subject: [PATCH] rest: add CallXML and DecodeXML functions --- rest/rest.go | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/rest/rest.go b/rest/rest.go index f754f3ddb..0668540e7 100644 --- a/rest/rest.go +++ b/rest/rest.go @@ -6,6 +6,7 @@ package rest import ( "bytes" "encoding/json" + "encoding/xml" "io" "io/ioutil" "mime/multipart" @@ -115,6 +116,13 @@ func DecodeJSON(resp *http.Response, result interface{}) (err error) { return decoder.Decode(result) } +// DecodeXML decodes resp.Body into result +func DecodeXML(resp *http.Response, result interface{}) (err error) { + defer fs.CheckClose(resp.Body, &err) + decoder := xml.NewDecoder(resp.Body) + return decoder.Decode(result) +} + // ClientWithHeaderReset makes a new http client which resets the // headers passed in on redirect // @@ -286,17 +294,35 @@ func MultipartUpload(in io.Reader, params url.Values, contentName, fileName stri // // It will return resp if at all possible, even if err is set func (api *Client) CallJSON(opts *Opts, request interface{}, response interface{}) (resp *http.Response, err error) { + return api.callCodec(opts, request, response, json.Marshal, DecodeJSON, "application/json") +} + +// CallXML runs Call and decodes the body as a XML object into response (if not nil) +// +// If request is not nil then it will be XML encoded as the body of the request +// +// See CallJSON for a description of MultipartParams and related opts +// +// It will return resp if at all possible, even if err is set +func (api *Client) CallXML(opts *Opts, request interface{}, response interface{}) (resp *http.Response, err error) { + return api.callCodec(opts, request, response, xml.Marshal, DecodeXML, "application/xml") +} + +type marshalFn func(v interface{}) ([]byte, error) +type decodeFn func(resp *http.Response, result interface{}) (err error) + +func (api *Client) callCodec(opts *Opts, request interface{}, response interface{}, marshal marshalFn, decode decodeFn, contentType string) (resp *http.Response, err error) { var requestBody []byte // Marshal the request if given if request != nil { - requestBody, err = json.Marshal(request) + requestBody, err = marshal(request) if err != nil { return nil, err } - // Set the body up as a JSON object if no body passed in + // Set the body up as a marshalled object if no body passed in if opts.Body == nil { opts = opts.Copy() - opts.ContentType = "application/json" + opts.ContentType = contentType opts.Body = bytes.NewBuffer(requestBody) } } @@ -322,6 +348,6 @@ func (api *Client) CallJSON(opts *Opts, request interface{}, response interface{ if response == nil || opts.NoResponse { return resp, nil } - err = DecodeJSON(resp, response) + err = decode(resp, response) return resp, err }