From 2058f8938710cf5ae26622871925a45b3237b0da Mon Sep 17 00:00:00 2001 From: Jeevanandam M Date: Mon, 5 Mar 2018 20:57:57 -0800 Subject: [PATCH] #134 added support for rfc7807 - application/problem+json and application/problem+xml --- README.md | 1 + client.go | 10 +++++----- request_test.go | 30 +++++++++++++++++++++++++++++- resty_test.go | 8 ++++++-- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9aa785d2..87b40a8f 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ Resty first version released on Sep 15, 2015 then it grew gradually as a very ha * For auto-unmarshal, refer to - - Success scenario [Request.SetResult()](https://godoc.org/github.com/go-resty/resty#Request.SetResult) and [Response.Result()](https://godoc.org/github.com/go-resty/resty#Response.Result). - Error scenario [Request.SetError()](https://godoc.org/github.com/go-resty/resty#Request.SetError) and [Response.Error()](https://godoc.org/github.com/go-resty/resty#Response.Error). + - Supports [RFC7807](https://tools.ietf.org/html/rfc7807) - `application/problem+json` & `application/problem+xml` * Easy to upload one or more file(s) via `multipart/form-data` * Auto detects file content type * Request URL [Path Params](https://godoc.org/github.com/go-resty/resty#Request.SetPathParams) diff --git a/client.go b/client.go index e7bb0978..2338fe51 100644 --- a/client.go +++ b/client.go @@ -56,8 +56,8 @@ var ( jsonContentType = "application/json; charset=utf-8" formContentType = "application/x-www-form-urlencoded" - jsonCheck = regexp.MustCompile("(?i:[application|text]/json)") - xmlCheck = regexp.MustCompile("(?i:[application|text]/xml)") + jsonCheck = regexp.MustCompile(`(?i:(application|text)/(problem\+json|json))`) + xmlCheck = regexp.MustCompile(`(?i:(application|text)/(problem\+xml|xml))`) hdrUserAgentValue = "go-resty v%s - https://github.com/go-resty/resty" bufPool = &sync.Pool{New: func() interface{} { return &bytes.Buffer{} }} @@ -869,8 +869,8 @@ func (f *File) String() string { // multipartField represent custom data part for multipart request type multipartField struct { - Param string - FileName string + Param string + FileName string ContentType string io.Reader -} \ No newline at end of file +} diff --git a/request_test.go b/request_test.go index 9644ca3b..72ecd286 100644 --- a/request_test.go +++ b/request_test.go @@ -214,8 +214,32 @@ func TestPostJSONStructInvalidLogin(t *testing.T) { assertError(t, err) assertEqual(t, http.StatusUnauthorized, resp.StatusCode()) - assertEqual(t, resp.Header().Get("Www-Authenticate"), "Protected Realm") + authError := resp.Error().(*AuthError) + assertEqual(t, "unauthorized", authError.ID) + assertEqual(t, "Invalid credentials", authError.Message) + t.Logf("Result Error: %q", resp.Error().(*AuthError)) + + logResponse(t, resp) +} + +func TestPostJSONErrorRFC7807(t *testing.T) { + ts := createPostServer(t) + defer ts.Close() + + c := dc() + resp, err := c.R(). + SetHeader(hdrContentTypeKey, jsonContentType). + SetBody(User{Username: "testuser", Password: "testpass1"}). + SetError(AuthError{}). + Post(ts.URL + "/login?ct=problem") + + assertError(t, err) + assertEqual(t, http.StatusUnauthorized, resp.StatusCode()) + + authError := resp.Error().(*AuthError) + assertEqual(t, "unauthorized", authError.ID) + assertEqual(t, "Invalid credentials", authError.Message) t.Logf("Result Error: %q", resp.Error().(*AuthError)) logResponse(t, resp) @@ -253,6 +277,10 @@ func TestPostJSONMapInvalidResponseJson(t *testing.T) { assertEqual(t, "invalid character '}' looking for beginning of object key string", err.Error()) assertEqual(t, http.StatusOK, resp.StatusCode()) + authSuccess := resp.Result().(*AuthSuccess) + assertEqual(t, "", authSuccess.ID) + assertEqual(t, "", authSuccess.Message) + t.Logf("Result Success: %q", resp.Result().(*AuthSuccess)) logResponse(t, resp) diff --git a/resty_test.go b/resty_test.go index 6a0afe41..9aa8c6f2 100644 --- a/resty_test.go +++ b/resty_test.go @@ -115,7 +115,12 @@ func handleLoginEndpoint(t *testing.T, w http.ResponseWriter, r *http.Request) { if IsJSONType(r.Header.Get(hdrContentTypeKey)) { jd := json.NewDecoder(r.Body) err := jd.Decode(user) - w.Header().Set(hdrContentTypeKey, jsonContentType) + if r.URL.Query().Get("ct") == "problem" { + w.Header().Set(hdrContentTypeKey, "application/problem+json; charset=utf-8") + } else { + w.Header().Set(hdrContentTypeKey, jsonContentType) + } + if err != nil { t.Logf("Error: %#v", err) w.WriteHeader(http.StatusBadRequest) @@ -128,7 +133,6 @@ func handleLoginEndpoint(t *testing.T, w http.ResponseWriter, r *http.Request) { } else if user.Username == "testuser" && user.Password == "invalidjson" { _, _ = w.Write([]byte(`{ "id": "success", "message": "login successful", }`)) } else { - w.Header().Set("Www-Authenticate", "Protected Realm") w.WriteHeader(http.StatusUnauthorized) _, _ = w.Write([]byte(`{ "id": "unauthorized", "message": "Invalid credentials" }`)) }