|
7 | 7 | "errors"
|
8 | 8 | "fmt"
|
9 | 9 | "io/ioutil"
|
| 10 | + "mime" |
10 | 11 | "net/http"
|
11 | 12 | "strings"
|
12 | 13 | "time"
|
@@ -93,18 +94,23 @@ func NewProvider(ctx context.Context, issuer string) (*Provider, error) {
|
93 | 94 | if err != nil {
|
94 | 95 | return nil, err
|
95 | 96 | }
|
| 97 | + defer resp.Body.Close() |
| 98 | + |
96 | 99 | body, err := ioutil.ReadAll(resp.Body)
|
97 | 100 | if err != nil {
|
98 |
| - return nil, err |
| 101 | + return nil, fmt.Errorf("unable to read response body: %v", err) |
99 | 102 | }
|
| 103 | + |
100 | 104 | if resp.StatusCode != http.StatusOK {
|
101 | 105 | return nil, fmt.Errorf("%s: %s", resp.Status, body)
|
102 | 106 | }
|
103 |
| - defer resp.Body.Close() |
| 107 | + |
104 | 108 | var p providerJSON
|
105 |
| - if err := json.Unmarshal(body, &p); err != nil { |
| 109 | + err = unmarshalResp(resp, body, &p) |
| 110 | + if err != nil { |
106 | 111 | return nil, fmt.Errorf("oidc: failed to decode provider discovery object: %v", err)
|
107 | 112 | }
|
| 113 | + |
108 | 114 | if p.Issuer != issuer {
|
109 | 115 | return nil, fmt.Errorf("oidc: issuer did not match the issuer returned by provider, expected %q got %q", issuer, p.Issuer)
|
110 | 116 | }
|
@@ -307,3 +313,16 @@ func (j *jsonTime) UnmarshalJSON(b []byte) error {
|
307 | 313 | *j = jsonTime(time.Unix(unix, 0))
|
308 | 314 | return nil
|
309 | 315 | }
|
| 316 | + |
| 317 | +func unmarshalResp(r *http.Response, body []byte, v interface{}) error { |
| 318 | + err := json.Unmarshal(body, &v) |
| 319 | + if err == nil { |
| 320 | + return nil |
| 321 | + } |
| 322 | + ct := r.Header.Get("Content-Type") |
| 323 | + mediaType, _, parseErr := mime.ParseMediaType(ct) |
| 324 | + if parseErr == nil && mediaType == "application/json" { |
| 325 | + return fmt.Errorf("got Content-Type = application/json, but could not unmarshal as JSON: %v", err) |
| 326 | + } |
| 327 | + return fmt.Errorf("expected Content-Type = application/json, got %q: %v", ct, err) |
| 328 | +} |
0 commit comments