Skip to content

Commit

Permalink
Client.AcceptProblemJSON()
Browse files Browse the repository at this point in the history
  • Loading branch information
Som-Som-CC committed Aug 6, 2021
1 parent 2e53525 commit 387df2b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 12 deletions.
29 changes: 20 additions & 9 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ var defaultClient = NewClient()

// Client is an instance of RESTful client.
type Client struct {
client *http.Client
sanitizeJSON bool
rootURL string
userAgent string
maxBytesToParse int
retries int
retryBackoffInit time.Duration
retryBackoffMax time.Duration
client *http.Client
sanitizeJSON bool
rootURL string
userAgent string
maxBytesToParse int
retries int
retryBackoffInit time.Duration
retryBackoffMax time.Duration
acceptProblemJSON bool
}

var h2CTransport = http2.Transport{
Expand Down Expand Up @@ -72,6 +73,7 @@ var h2Transport = http2.Transport{
func NewClient() *Client {
c := &Client{}
c.client = &http.Client{}
c.acceptProblemJSON = true /* backward compatible */
return c
}

Expand All @@ -95,6 +97,13 @@ func (c *Client) UserAgent(userAgent string) *Client {
return c
}

// AcceptProblemJSON sets whether client is to send "Accept: application/problem+json" header.
// I.e. tells the server whether your client wants RFC 7807 answers.
func (c *Client) AcceptProblemJSON(acceptProblemJSON bool) *Client {
c.acceptProblemJSON = acceptProblemJSON
return c
}

// Root sets default root URL for client. Returns object instance, just in case you need that.
// You may use it this way: client := New().Root(...) or just client.Root(...)
func (c *Client) Root(rootURL string) *Client {
Expand Down Expand Up @@ -303,7 +312,9 @@ func (c *Client) sendRequestBytes(ctx context.Context, method string, target str

if req.Header.Get(AcceptHeader) == "" {
req.Header.Set(AcceptHeader, ContentTypeApplicationJSON)
req.Header.Add(AcceptHeader, ContentTypeProblemJSON)
if c.acceptProblemJSON {
req.Header.Add(AcceptHeader, ContentTypeProblemJSON)
}
}

return c.Do(ctx, req)
Expand Down
23 changes: 21 additions & 2 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,14 +262,32 @@ func TestGet500(t *testing.T) {
}))
defer srv.Close()

err := Get(context.Background(), srv.URL, nil)
c := NewClient().AcceptProblemJSON(true)
err := c.Get(context.Background(), srv.URL, nil)
assert.Error(err)
assert.NotEmpty(err.Error())
assert.Equal(problem, err.Error())
assert.Equal(http.StatusInternalServerError, GetErrStatusCode(err))
assert.Equal(http.StatusInternalServerError, GetErrStatusCodeElse(err, 0))
}

func TestGet500NoProblemJSON(t *testing.T) {
assert := assert.New(t)
const problem = `{"title":"Configuration error"}`

// Server
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
acc := r.Header["Accept"]
assert.Equal(1, len(acc)) // json only
SendResp(w, r, NewError(nil, 500, problem), nil)
}))
defer srv.Close()

c := NewClient().AcceptProblemJSON(false)
err := c.Get(context.Background(), srv.URL, nil)
assert.Error(err)
}

func TestGet500Details(t *testing.T) {
assert := assert.New(t)

Expand All @@ -288,7 +306,8 @@ func TestGet500Details(t *testing.T) {
}))
defer srv.Close()

err := Get(context.Background(), srv.URL, nil)
c := NewClient().AcceptProblemJSON(true)
err := c.Get(context.Background(), srv.URL, nil)
assert.Error(err)
assert.NotEmpty(err.Error())
assert.Equal("{\"title\":\"title\",\"detail\":\"descr\",\"invalidParams\":{\"param1\":\"error text\"}}", err.Error())
Expand Down
2 changes: 1 addition & 1 deletion contenttype.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const (
ContentTypeAny = "*/*"
ContentTypeApplicationAny = "application/*"
ContentTypeApplicationJSON = "application/json"
ContentTypeProblemJSON = "application/problem+json"
ContentTypeProblemJSON = "application/problem+json" // RFC 7807
ContentTypePatchJSON = "application/json-patch+json" // RFC 6902
ContentTypeMergeJSON = "application/merge-patch+json" // RFC 7386
ContentTypeForm = "application/x-www-form-urlencoded"
Expand Down

0 comments on commit 387df2b

Please sign in to comment.