Skip to content

Commit ec636bb

Browse files
author
Aaron Lehmann
committed
Handle nonstandard token endpoint errors
#1249 changed token fetching to parse HTTP error response bodies as serialized errcodes. However, Docker Hub's authentication endpoint does not return error bodies in this format. To work around this, convert its format into ErrCodeUnauthorized or ErrCodeUnknown. Signed-off-by: Aaron Lehmann <[email protected]>
1 parent dd0d5a3 commit ec636bb

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

registry/api/errcode/errors.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,15 @@ func (ec *ErrorCode) UnmarshalText(text []byte) error {
6969
return nil
7070
}
7171

72+
// WithMessage creates a new Error struct based on the passed-in info and
73+
// overrides the Message property.
74+
func (ec ErrorCode) WithMessage(message string) Error {
75+
return Error{
76+
Code: ec,
77+
Message: message,
78+
}
79+
}
80+
7281
// WithDetail creates a new Error struct based on the passed-in info and
7382
// set the Detail property appropriately
7483
func (ec ErrorCode) WithDetail(detail interface{}) Error {

registry/client/errors.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,26 @@ func (e *UnexpectedHTTPResponseError) Error() string {
3131
return fmt.Sprintf("Error parsing HTTP response: %s: %q", e.ParseErr.Error(), string(e.Response))
3232
}
3333

34-
func parseHTTPErrorResponse(r io.Reader) error {
34+
func parseHTTPErrorResponse(statusCode int, r io.Reader) error {
3535
var errors errcode.Errors
3636
body, err := ioutil.ReadAll(r)
3737
if err != nil {
3838
return err
3939
}
4040

41+
// For backward compatibility, handle irregularly formatted
42+
// messages that contain a "details" field.
43+
var detailsErr struct {
44+
Details string `json:"details"`
45+
}
46+
err = json.Unmarshal(body, &detailsErr)
47+
if err == nil && detailsErr.Details != "" {
48+
if statusCode == http.StatusUnauthorized {
49+
return errcode.ErrorCodeUnauthorized.WithMessage(detailsErr.Details)
50+
}
51+
return errcode.ErrorCodeUnknown.WithMessage(detailsErr.Details)
52+
}
53+
4154
if err := json.Unmarshal(body, &errors); err != nil {
4255
return &UnexpectedHTTPResponseError{
4356
ParseErr: err,
@@ -53,14 +66,14 @@ func parseHTTPErrorResponse(r io.Reader) error {
5366
// range.
5467
func HandleErrorResponse(resp *http.Response) error {
5568
if resp.StatusCode == 401 {
56-
err := parseHTTPErrorResponse(resp.Body)
69+
err := parseHTTPErrorResponse(resp.StatusCode, resp.Body)
5770
if uErr, ok := err.(*UnexpectedHTTPResponseError); ok {
5871
return errcode.ErrorCodeUnauthorized.WithDetail(uErr.Response)
5972
}
6073
return err
6174
}
6275
if resp.StatusCode >= 400 && resp.StatusCode < 500 {
63-
return parseHTTPErrorResponse(resp.Body)
76+
return parseHTTPErrorResponse(resp.StatusCode, resp.Body)
6477
}
6578
return &UnexpectedHTTPStatusError{Status: resp.Status}
6679
}

0 commit comments

Comments
 (0)