diff options
Diffstat (limited to 'vendor/github.com/minio/minio-go/v7/api-error-response.go')
-rw-r--r-- | vendor/github.com/minio/minio-go/v7/api-error-response.go | 284 |
1 files changed, 0 insertions, 284 deletions
diff --git a/vendor/github.com/minio/minio-go/v7/api-error-response.go b/vendor/github.com/minio/minio-go/v7/api-error-response.go deleted file mode 100644 index 7df211f..0000000 --- a/vendor/github.com/minio/minio-go/v7/api-error-response.go +++ /dev/null | |||
@@ -1,284 +0,0 @@ | |||
1 | /* | ||
2 | * MinIO Go Library for Amazon S3 Compatible Cloud Storage | ||
3 | * Copyright 2015-2020 MinIO, Inc. | ||
4 | * | ||
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | * you may not use this file except in compliance with the License. | ||
7 | * You may obtain a copy of the License at | ||
8 | * | ||
9 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | * | ||
11 | * Unless required by applicable law or agreed to in writing, software | ||
12 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | * See the License for the specific language governing permissions and | ||
15 | * limitations under the License. | ||
16 | */ | ||
17 | |||
18 | package minio | ||
19 | |||
20 | import ( | ||
21 | "bytes" | ||
22 | "encoding/xml" | ||
23 | "fmt" | ||
24 | "io" | ||
25 | "net/http" | ||
26 | "strings" | ||
27 | ) | ||
28 | |||
29 | /* **** SAMPLE ERROR RESPONSE **** | ||
30 | <?xml version="1.0" encoding="UTF-8"?> | ||
31 | <Error> | ||
32 | <Code>AccessDenied</Code> | ||
33 | <Message>Access Denied</Message> | ||
34 | <BucketName>bucketName</BucketName> | ||
35 | <Key>objectName</Key> | ||
36 | <RequestId>F19772218238A85A</RequestId> | ||
37 | <HostId>GuWkjyviSiGHizehqpmsD1ndz5NClSP19DOT+s2mv7gXGQ8/X1lhbDGiIJEXpGFD</HostId> | ||
38 | </Error> | ||
39 | */ | ||
40 | |||
41 | // ErrorResponse - Is the typed error returned by all API operations. | ||
42 | // ErrorResponse struct should be comparable since it is compared inside | ||
43 | // golang http API (https://github.com/golang/go/issues/29768) | ||
44 | type ErrorResponse struct { | ||
45 | XMLName xml.Name `xml:"Error" json:"-"` | ||
46 | Code string | ||
47 | Message string | ||
48 | BucketName string | ||
49 | Key string | ||
50 | Resource string | ||
51 | RequestID string `xml:"RequestId"` | ||
52 | HostID string `xml:"HostId"` | ||
53 | |||
54 | // Region where the bucket is located. This header is returned | ||
55 | // only in HEAD bucket and ListObjects response. | ||
56 | Region string | ||
57 | |||
58 | // Captures the server string returned in response header. | ||
59 | Server string | ||
60 | |||
61 | // Underlying HTTP status code for the returned error | ||
62 | StatusCode int `xml:"-" json:"-"` | ||
63 | } | ||
64 | |||
65 | // ToErrorResponse - Returns parsed ErrorResponse struct from body and | ||
66 | // http headers. | ||
67 | // | ||
68 | // For example: | ||
69 | // | ||
70 | // import s3 "github.com/minio/minio-go/v7" | ||
71 | // ... | ||
72 | // ... | ||
73 | // reader, stat, err := s3.GetObject(...) | ||
74 | // if err != nil { | ||
75 | // resp := s3.ToErrorResponse(err) | ||
76 | // } | ||
77 | // ... | ||
78 | func ToErrorResponse(err error) ErrorResponse { | ||
79 | switch err := err.(type) { | ||
80 | case ErrorResponse: | ||
81 | return err | ||
82 | default: | ||
83 | return ErrorResponse{} | ||
84 | } | ||
85 | } | ||
86 | |||
87 | // Error - Returns S3 error string. | ||
88 | func (e ErrorResponse) Error() string { | ||
89 | if e.Message == "" { | ||
90 | msg, ok := s3ErrorResponseMap[e.Code] | ||
91 | if !ok { | ||
92 | msg = fmt.Sprintf("Error response code %s.", e.Code) | ||
93 | } | ||
94 | return msg | ||
95 | } | ||
96 | return e.Message | ||
97 | } | ||
98 | |||
99 | // Common string for errors to report issue location in unexpected | ||
100 | // cases. | ||
101 | const ( | ||
102 | reportIssue = "Please report this issue at https://github.com/minio/minio-go/issues." | ||
103 | ) | ||
104 | |||
105 | // xmlDecodeAndBody reads the whole body up to 1MB and | ||
106 | // tries to XML decode it into v. | ||
107 | // The body that was read and any error from reading or decoding is returned. | ||
108 | func xmlDecodeAndBody(bodyReader io.Reader, v interface{}) ([]byte, error) { | ||
109 | // read the whole body (up to 1MB) | ||
110 | const maxBodyLength = 1 << 20 | ||
111 | body, err := io.ReadAll(io.LimitReader(bodyReader, maxBodyLength)) | ||
112 | if err != nil { | ||
113 | return nil, err | ||
114 | } | ||
115 | return bytes.TrimSpace(body), xmlDecoder(bytes.NewReader(body), v) | ||
116 | } | ||
117 | |||
118 | // httpRespToErrorResponse returns a new encoded ErrorResponse | ||
119 | // structure as error. | ||
120 | func httpRespToErrorResponse(resp *http.Response, bucketName, objectName string) error { | ||
121 | if resp == nil { | ||
122 | msg := "Empty http response. " + reportIssue | ||
123 | return errInvalidArgument(msg) | ||
124 | } | ||
125 | |||
126 | errResp := ErrorResponse{ | ||
127 | StatusCode: resp.StatusCode, | ||
128 | Server: resp.Header.Get("Server"), | ||
129 | } | ||
130 | |||
131 | errBody, err := xmlDecodeAndBody(resp.Body, &errResp) | ||
132 | // Xml decoding failed with no body, fall back to HTTP headers. | ||
133 | if err != nil { | ||
134 | switch resp.StatusCode { | ||
135 | case http.StatusNotFound: | ||
136 | if objectName == "" { | ||
137 | errResp = ErrorResponse{ | ||
138 | StatusCode: resp.StatusCode, | ||
139 | Code: "NoSuchBucket", | ||
140 | Message: "The specified bucket does not exist.", | ||
141 | BucketName: bucketName, | ||
142 | } | ||
143 | } else { | ||
144 | errResp = ErrorResponse{ | ||
145 | StatusCode: resp.StatusCode, | ||
146 | Code: "NoSuchKey", | ||
147 | Message: "The specified key does not exist.", | ||
148 | BucketName: bucketName, | ||
149 | Key: objectName, | ||
150 | } | ||
151 | } | ||
152 | case http.StatusForbidden: | ||
153 | errResp = ErrorResponse{ | ||
154 | StatusCode: resp.StatusCode, | ||
155 | Code: "AccessDenied", | ||
156 | Message: "Access Denied.", | ||
157 | BucketName: bucketName, | ||
158 | Key: objectName, | ||
159 | } | ||
160 | case http.StatusConflict: | ||
161 | errResp = ErrorResponse{ | ||
162 | StatusCode: resp.StatusCode, | ||
163 | Code: "Conflict", | ||
164 | Message: "Bucket not empty.", | ||
165 | BucketName: bucketName, | ||
166 | } | ||
167 | case http.StatusPreconditionFailed: | ||
168 | errResp = ErrorResponse{ | ||
169 | StatusCode: resp.StatusCode, | ||
170 | Code: "PreconditionFailed", | ||
171 | Message: s3ErrorResponseMap["PreconditionFailed"], | ||
172 | BucketName: bucketName, | ||
173 | Key: objectName, | ||
174 | } | ||
175 | default: | ||
176 | msg := resp.Status | ||
177 | if len(errBody) > 0 { | ||
178 | msg = string(errBody) | ||
179 | if len(msg) > 1024 { | ||
180 | msg = msg[:1024] + "..." | ||
181 | } | ||
182 | } | ||
183 | errResp = ErrorResponse{ | ||
184 | StatusCode: resp.StatusCode, | ||
185 | Code: resp.Status, | ||
186 | Message: msg, | ||
187 | BucketName: bucketName, | ||
188 | } | ||
189 | } | ||
190 | } | ||
191 | |||
192 | code := resp.Header.Get("x-minio-error-code") | ||
193 | if code != "" { | ||
194 | errResp.Code = code | ||
195 | } | ||
196 | desc := resp.Header.Get("x-minio-error-desc") | ||
197 | if desc != "" { | ||
198 | errResp.Message = strings.Trim(desc, `"`) | ||
199 | } | ||
200 | |||
201 | // Save hostID, requestID and region information | ||
202 | // from headers if not available through error XML. | ||
203 | if errResp.RequestID == "" { | ||
204 | errResp.RequestID = resp.Header.Get("x-amz-request-id") | ||
205 | } | ||
206 | if errResp.HostID == "" { | ||
207 | errResp.HostID = resp.Header.Get("x-amz-id-2") | ||
208 | } | ||
209 | if errResp.Region == "" { | ||
210 | errResp.Region = resp.Header.Get("x-amz-bucket-region") | ||
211 | } | ||
212 | if errResp.Code == "InvalidRegion" && errResp.Region != "" { | ||
213 | errResp.Message = fmt.Sprintf("Region does not match, expecting region ‘%s’.", errResp.Region) | ||
214 | } | ||
215 | |||
216 | return errResp | ||
217 | } | ||
218 | |||
219 | // errTransferAccelerationBucket - bucket name is invalid to be used with transfer acceleration. | ||
220 | func errTransferAccelerationBucket(bucketName string) error { | ||
221 | return ErrorResponse{ | ||
222 | StatusCode: http.StatusBadRequest, | ||
223 | Code: "InvalidArgument", | ||
224 | Message: "The name of the bucket used for Transfer Acceleration must be DNS-compliant and must not contain periods ‘.’.", | ||
225 | BucketName: bucketName, | ||
226 | } | ||
227 | } | ||
228 | |||
229 | // errEntityTooLarge - Input size is larger than supported maximum. | ||
230 | func errEntityTooLarge(totalSize, maxObjectSize int64, bucketName, objectName string) error { | ||
231 | msg := fmt.Sprintf("Your proposed upload size ‘%d’ exceeds the maximum allowed object size ‘%d’ for single PUT operation.", totalSize, maxObjectSize) | ||
232 | return ErrorResponse{ | ||
233 | StatusCode: http.StatusBadRequest, | ||
234 | Code: "EntityTooLarge", | ||
235 | Message: msg, | ||
236 | BucketName: bucketName, | ||
237 | Key: objectName, | ||
238 | } | ||
239 | } | ||
240 | |||
241 | // errEntityTooSmall - Input size is smaller than supported minimum. | ||
242 | func errEntityTooSmall(totalSize int64, bucketName, objectName string) error { | ||
243 | msg := fmt.Sprintf("Your proposed upload size ‘%d’ is below the minimum allowed object size ‘0B’ for single PUT operation.", totalSize) | ||
244 | return ErrorResponse{ | ||
245 | StatusCode: http.StatusBadRequest, | ||
246 | Code: "EntityTooSmall", | ||
247 | Message: msg, | ||
248 | BucketName: bucketName, | ||
249 | Key: objectName, | ||
250 | } | ||
251 | } | ||
252 | |||
253 | // errUnexpectedEOF - Unexpected end of file reached. | ||
254 | func errUnexpectedEOF(totalRead, totalSize int64, bucketName, objectName string) error { | ||
255 | msg := fmt.Sprintf("Data read ‘%d’ is not equal to the size ‘%d’ of the input Reader.", totalRead, totalSize) | ||
256 | return ErrorResponse{ | ||
257 | StatusCode: http.StatusBadRequest, | ||
258 | Code: "UnexpectedEOF", | ||
259 | Message: msg, | ||
260 | BucketName: bucketName, | ||
261 | Key: objectName, | ||
262 | } | ||
263 | } | ||
264 | |||
265 | // errInvalidArgument - Invalid argument response. | ||
266 | func errInvalidArgument(message string) error { | ||
267 | return ErrorResponse{ | ||
268 | StatusCode: http.StatusBadRequest, | ||
269 | Code: "InvalidArgument", | ||
270 | Message: message, | ||
271 | RequestID: "minio", | ||
272 | } | ||
273 | } | ||
274 | |||
275 | // errAPINotSupported - API not supported response | ||
276 | // The specified API call is not supported | ||
277 | func errAPINotSupported(message string) error { | ||
278 | return ErrorResponse{ | ||
279 | StatusCode: http.StatusNotImplemented, | ||
280 | Code: "APINotSupported", | ||
281 | Message: message, | ||
282 | RequestID: "minio", | ||
283 | } | ||
284 | } | ||