Commit 32a277faa69bf209d3583f74687bae4f8993eccf
1 parent
765a887d9c
Exists in
master
handle unsuccessful status codes
Showing
1 changed file
with
8 additions
and
0 deletions
Show diff stats
json.go
1 | package webutility | 1 | package webutility |
2 | 2 | ||
3 | // TODO(marko): If DecodeJSON() returns io.EOF treat it as if there is no response body, since response content length can sometimes be -1. | 3 | // TODO(marko): If DecodeJSON() returns io.EOF treat it as if there is no response body, since response content length can sometimes be -1. |
4 | 4 | ||
5 | import ( | 5 | import ( |
6 | "bytes" | 6 | "bytes" |
7 | "encoding/json" | 7 | "encoding/json" |
8 | "io" | 8 | "io" |
9 | "net/http" | 9 | "net/http" |
10 | "net/url" | 10 | "net/url" |
11 | ) | 11 | ) |
12 | 12 | ||
13 | // DecodeJSON decodes JSON data from r to v. | 13 | // DecodeJSON decodes JSON data from r to v. |
14 | // Returns an error if it fails. | 14 | // Returns an error if it fails. |
15 | func DecodeJSON(r io.Reader, v interface{}) error { | 15 | func DecodeJSON(r io.Reader, v interface{}) error { |
16 | return json.NewDecoder(r).Decode(v) | 16 | return json.NewDecoder(r).Decode(v) |
17 | } | 17 | } |
18 | 18 | ||
19 | func GetJSON(url string, v interface{}, params url.Values, headers http.Header) (status int, err error) { | 19 | func GetJSON(url string, v interface{}, params url.Values, headers http.Header) (status int, err error) { |
20 | p := params.Encode() | 20 | p := params.Encode() |
21 | if p != "" { | 21 | if p != "" { |
22 | url += "?" + p | 22 | url += "?" + p |
23 | } | 23 | } |
24 | 24 | ||
25 | req, err := http.NewRequest(http.MethodGet, url, nil) | 25 | req, err := http.NewRequest(http.MethodGet, url, nil) |
26 | if err != nil { | 26 | if err != nil { |
27 | return 0, err | 27 | return 0, err |
28 | } | 28 | } |
29 | 29 | ||
30 | if headers != nil { | 30 | if headers != nil { |
31 | for k, head := range headers { | 31 | for k, head := range headers { |
32 | for i, h := range head { | 32 | for i, h := range head { |
33 | if i == 0 { | 33 | if i == 0 { |
34 | req.Header.Set(k, h) | 34 | req.Header.Set(k, h) |
35 | } else { | 35 | } else { |
36 | req.Header.Add(k, h) | 36 | req.Header.Add(k, h) |
37 | } | 37 | } |
38 | } | 38 | } |
39 | } | 39 | } |
40 | } | 40 | } |
41 | 41 | ||
42 | resp, err := http.DefaultClient.Do(req) | 42 | resp, err := http.DefaultClient.Do(req) |
43 | if err != nil { | 43 | if err != nil { |
44 | return 0, err | 44 | return 0, err |
45 | } | 45 | } |
46 | defer resp.Body.Close() | 46 | defer resp.Body.Close() |
47 | status = resp.StatusCode | 47 | status = resp.StatusCode |
48 | 48 | ||
49 | if status != http.StatusOK { | ||
50 | return status, err | ||
51 | } | ||
52 | |||
49 | if err = DecodeJSON(resp.Body, v); err == io.EOF { | 53 | if err = DecodeJSON(resp.Body, v); err == io.EOF { |
50 | err = nil | 54 | err = nil |
51 | } | 55 | } |
52 | 56 | ||
53 | return status, err | 57 | return status, err |
54 | } | 58 | } |
55 | 59 | ||
56 | func PostJSON(url string, v, r interface{}, params url.Values, headers http.Header) (status int, err error) { | 60 | func PostJSON(url string, v, r interface{}, params url.Values, headers http.Header) (status int, err error) { |
57 | buffer := bytes.NewBuffer(make([]byte, 0)) | 61 | buffer := bytes.NewBuffer(make([]byte, 0)) |
58 | json.NewEncoder(buffer).Encode(v) | 62 | json.NewEncoder(buffer).Encode(v) |
59 | 63 | ||
60 | p := params.Encode() | 64 | p := params.Encode() |
61 | if p != "" { | 65 | if p != "" { |
62 | url += "?" + p | 66 | url += "?" + p |
63 | } | 67 | } |
64 | 68 | ||
65 | req, err := http.NewRequest(http.MethodPost, url, buffer) | 69 | req, err := http.NewRequest(http.MethodPost, url, buffer) |
66 | if err != nil { | 70 | if err != nil { |
67 | return 0, err | 71 | return 0, err |
68 | } | 72 | } |
69 | 73 | ||
70 | if headers != nil { | 74 | if headers != nil { |
71 | for k, head := range headers { | 75 | for k, head := range headers { |
72 | for i, h := range head { | 76 | for i, h := range head { |
73 | if i == 0 { | 77 | if i == 0 { |
74 | req.Header.Set(k, h) | 78 | req.Header.Set(k, h) |
75 | } else { | 79 | } else { |
76 | req.Header.Add(k, h) | 80 | req.Header.Add(k, h) |
77 | } | 81 | } |
78 | } | 82 | } |
79 | } | 83 | } |
80 | } | 84 | } |
81 | req.Header.Set("Content-Type", "application/json") | 85 | req.Header.Set("Content-Type", "application/json") |
82 | 86 | ||
83 | resp, err := http.DefaultClient.Do(req) | 87 | resp, err := http.DefaultClient.Do(req) |
84 | if err != nil { | 88 | if err != nil { |
85 | return 0, err | 89 | return 0, err |
86 | } | 90 | } |
87 | status = resp.StatusCode | 91 | status = resp.StatusCode |
88 | defer resp.Body.Close() | 92 | defer resp.Body.Close() |
89 | 93 | ||
94 | if status != http.StatusOK && status != http.StatusCreated { | ||
95 | return status, err | ||
96 | } | ||
97 | |||
90 | if err = DecodeJSON(resp.Body, v); err == io.EOF { | 98 | if err = DecodeJSON(resp.Body, v); err == io.EOF { |
91 | err = nil | 99 | err = nil |
92 | } | 100 | } |
93 | 101 | ||
94 | return status, err | 102 | return status, err |
95 | } | 103 | } |
96 | 104 |