azure: handle encryption headers and azure InvalidMetadata error (#4893)

Previously minio gateway returns invalid bucket name error for invalid
meta data.  This is fixed by returning BadRequest with 'Unsupported
metadata' in response.

Fixes #4891
This commit is contained in:
Bala FA 2017-09-12 16:14:41 -07:00 committed by Dee Koder
parent b9fc4150f6
commit 302fcb3b17
4 changed files with 55 additions and 8 deletions

View file

@ -117,6 +117,7 @@ const (
ErrNotSupported
ErrBucketAlreadyExists
ErrMetadataTooLarge
ErrUnsupportedMetadata
// Add new error codes here.
// Bucket notification related errors.
@ -654,6 +655,11 @@ var errorCodeResponse = map[APIErrorCode]APIError{
Description: "Your metadata headers exceed the maximum allowed metadata size.",
HTTPStatusCode: http.StatusBadRequest,
},
ErrUnsupportedMetadata: {
Code: "InvalidArgument",
Description: "Your metadata headers are not supported.",
HTTPStatusCode: http.StatusBadRequest,
},
// Add your error structure here.
}
@ -750,6 +756,8 @@ func toAPIErrorCode(err error) (apiErr APIErrorCode) {
apiErr = ErrNoSuchBucketPolicy
case PartTooBig:
apiErr = ErrEntityTooLarge
case UnsupportedMetadata:
apiErr = ErrUnsupportedMetadata
default:
apiErr = ErrInternalError
}

View file

@ -45,9 +45,18 @@ const azureBlockSize = 100 * humanize.MiByte
// Also replaces X-Amz-Meta prefix with X-Ms-Meta as Azure expects user
// defined metadata to have X-Ms-Meta prefix.
func s3ToAzureHeaders(headers map[string]string) (newHeaders map[string]string) {
gatewayHeaders := map[string]string{
"X-Amz-Meta-X-Amz-Key": "X-Amz-Meta-x_minio_key",
"X-Amz-Meta-X-Amz-Matdesc": "X-Amz-Meta-x_minio_matdesc",
"X-Amz-Meta-X-Amz-Iv": "X-Amz-Meta-x_minio_iv",
}
newHeaders = make(map[string]string)
for k, v := range headers {
k = http.CanonicalHeaderKey(k)
if nk, ok := gatewayHeaders[k]; ok {
k = nk
}
if strings.HasPrefix(k, "X-Amz-Meta") {
k = strings.Replace(k, "X-Amz-Meta", "X-Ms-Meta", -1)
}
@ -59,10 +68,19 @@ func s3ToAzureHeaders(headers map[string]string) (newHeaders map[string]string)
// Prefix user metadata with "X-Amz-Meta-".
// client.GetBlobMetadata() already strips "X-Ms-Meta-"
func azureToS3Metadata(meta map[string]string) (newMeta map[string]string) {
gatewayHeaders := map[string]string{
"X-Amz-Meta-x_minio_key": "X-Amz-Meta-X-Amz-Key",
"X-Amz-Meta-x_minio_matdesc": "X-Amz-Meta-X-Amz-Matdesc",
"X-Amz-Meta-x_minio_iv": "X-Amz-Meta-X-Amz-Iv",
}
newMeta = make(map[string]string)
for k, v := range meta {
k = "X-Amz-Meta-" + k
if nk, ok := gatewayHeaders[k]; ok {
k = nk
}
newMeta[k] = v
}
return newMeta
@ -145,6 +163,8 @@ func azureToObjectError(err error, params ...string) error {
err = BucketNameInvalid{Bucket: bucket}
case "RequestBodyTooLarge":
err = PartTooBig{}
case "InvalidMetadata":
err = UnsupportedMetadata{}
default:
switch azureErr.StatusCode {
case http.StatusNotFound:

View file

@ -45,14 +45,20 @@ func TestAzureToS3ETag(t *testing.T) {
// Test canonical metadata.
func TestS3ToAzureHeaders(t *testing.T) {
headers := map[string]string{
"accept-encoding": "gzip",
"content-encoding": "gzip",
"X-Amz-Meta-Hdr": "value",
"accept-encoding": "gzip",
"content-encoding": "gzip",
"X-Amz-Meta-Hdr": "value",
"X-Amz-Meta-X-Amz-Key": "hu3ZSqtqwn+aL4V2VhAeov4i+bG3KyCtRMSXQFRHXOk=",
"X-Amz-Meta-X-Amz-Matdesc": "{}",
"X-Amz-Meta-X-Amz-Iv": "eWmyryl8kq+EVnnsE7jpOg==",
}
expectedHeaders := map[string]string{
"Accept-Encoding": "gzip",
"Content-Encoding": "gzip",
"X-Ms-Meta-Hdr": "value",
"Accept-Encoding": "gzip",
"Content-Encoding": "gzip",
"X-Ms-Meta-Hdr": "value",
"X-Ms-Meta-x_minio_key": "hu3ZSqtqwn+aL4V2VhAeov4i+bG3KyCtRMSXQFRHXOk=",
"X-Ms-Meta-x_minio_matdesc": "{}",
"X-Ms-Meta-x_minio_iv": "eWmyryl8kq+EVnnsE7jpOg==",
}
actualHeaders := s3ToAzureHeaders(headers)
if !reflect.DeepEqual(actualHeaders, expectedHeaders) {
@ -64,10 +70,16 @@ func TestAzureToS3Metadata(t *testing.T) {
// Just one testcase. Adding more test cases does not add value to the testcase
// as azureToS3Metadata() just adds a prefix.
metadata := map[string]string{
"First-Name": "myname",
"First-Name": "myname",
"x_minio_key": "hu3ZSqtqwn+aL4V2VhAeov4i+bG3KyCtRMSXQFRHXOk=",
"x_minio_matdesc": "{}",
"x_minio_iv": "eWmyryl8kq+EVnnsE7jpOg==",
}
expectedMeta := map[string]string{
"X-Amz-Meta-First-Name": "myname",
"X-Amz-Meta-First-Name": "myname",
"X-Amz-Meta-X-Amz-Key": "hu3ZSqtqwn+aL4V2VhAeov4i+bG3KyCtRMSXQFRHXOk=",
"X-Amz-Meta-X-Amz-Matdesc": "{}",
"X-Amz-Meta-X-Amz-Iv": "eWmyryl8kq+EVnnsE7jpOg==",
}
actualMeta := azureToS3Metadata(metadata)
if !reflect.DeepEqual(actualMeta, expectedMeta) {

View file

@ -387,6 +387,13 @@ func (e PolicyNotFound) Error() string {
return "Policy not found"
}
// UnsupportedMetadata - unsupported metadata
type UnsupportedMetadata struct{}
func (e UnsupportedMetadata) Error() string {
return "Unsupported headers in Metadata"
}
// Check if error type is IncompleteBody.
func isErrIncompleteBody(err error) bool {
err = errorCause(err)