diff options
Diffstat (limited to 'vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go')
-rw-r--r-- | vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go new file mode 100644 index 0000000..bcca862 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go | |||
@@ -0,0 +1,103 @@ | |||
1 | package s3 | ||
2 | |||
3 | import ( | ||
4 | "encoding/xml" | ||
5 | "fmt" | ||
6 | "io" | ||
7 | "io/ioutil" | ||
8 | "net/http" | ||
9 | "strings" | ||
10 | |||
11 | "github.com/aws/aws-sdk-go/aws" | ||
12 | "github.com/aws/aws-sdk-go/aws/awserr" | ||
13 | "github.com/aws/aws-sdk-go/aws/request" | ||
14 | ) | ||
15 | |||
16 | type xmlErrorResponse struct { | ||
17 | XMLName xml.Name `xml:"Error"` | ||
18 | Code string `xml:"Code"` | ||
19 | Message string `xml:"Message"` | ||
20 | } | ||
21 | |||
22 | func unmarshalError(r *request.Request) { | ||
23 | defer r.HTTPResponse.Body.Close() | ||
24 | defer io.Copy(ioutil.Discard, r.HTTPResponse.Body) | ||
25 | |||
26 | hostID := r.HTTPResponse.Header.Get("X-Amz-Id-2") | ||
27 | |||
28 | // Bucket exists in a different region, and request needs | ||
29 | // to be made to the correct region. | ||
30 | if r.HTTPResponse.StatusCode == http.StatusMovedPermanently { | ||
31 | r.Error = requestFailure{ | ||
32 | RequestFailure: awserr.NewRequestFailure( | ||
33 | awserr.New("BucketRegionError", | ||
34 | fmt.Sprintf("incorrect region, the bucket is not in '%s' region", | ||
35 | aws.StringValue(r.Config.Region)), | ||
36 | nil), | ||
37 | r.HTTPResponse.StatusCode, | ||
38 | r.RequestID, | ||
39 | ), | ||
40 | hostID: hostID, | ||
41 | } | ||
42 | return | ||
43 | } | ||
44 | |||
45 | var errCode, errMsg string | ||
46 | |||
47 | // Attempt to parse error from body if it is known | ||
48 | resp := &xmlErrorResponse{} | ||
49 | err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) | ||
50 | if err != nil && err != io.EOF { | ||
51 | errCode = "SerializationError" | ||
52 | errMsg = "failed to decode S3 XML error response" | ||
53 | } else { | ||
54 | errCode = resp.Code | ||
55 | errMsg = resp.Message | ||
56 | err = nil | ||
57 | } | ||
58 | |||
59 | // Fallback to status code converted to message if still no error code | ||
60 | if len(errCode) == 0 { | ||
61 | statusText := http.StatusText(r.HTTPResponse.StatusCode) | ||
62 | errCode = strings.Replace(statusText, " ", "", -1) | ||
63 | errMsg = statusText | ||
64 | } | ||
65 | |||
66 | r.Error = requestFailure{ | ||
67 | RequestFailure: awserr.NewRequestFailure( | ||
68 | awserr.New(errCode, errMsg, err), | ||
69 | r.HTTPResponse.StatusCode, | ||
70 | r.RequestID, | ||
71 | ), | ||
72 | hostID: hostID, | ||
73 | } | ||
74 | } | ||
75 | |||
76 | // A RequestFailure provides access to the S3 Request ID and Host ID values | ||
77 | // returned from API operation errors. Getting the error as a string will | ||
78 | // return the formated error with the same information as awserr.RequestFailure, | ||
79 | // while also adding the HostID value from the response. | ||
80 | type RequestFailure interface { | ||
81 | awserr.RequestFailure | ||
82 | |||
83 | // Host ID is the S3 Host ID needed for debug, and contacting support | ||
84 | HostID() string | ||
85 | } | ||
86 | |||
87 | type requestFailure struct { | ||
88 | awserr.RequestFailure | ||
89 | |||
90 | hostID string | ||
91 | } | ||
92 | |||
93 | func (r requestFailure) Error() string { | ||
94 | extra := fmt.Sprintf("status code: %d, request id: %s, host id: %s", | ||
95 | r.StatusCode(), r.RequestID(), r.hostID) | ||
96 | return awserr.SprintError(r.Code(), r.Message(), extra, r.OrigErr()) | ||
97 | } | ||
98 | func (r requestFailure) String() string { | ||
99 | return r.Error() | ||
100 | } | ||
101 | func (r requestFailure) HostID() string { | ||
102 | return r.hostID | ||
103 | } | ||