| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | /* | 
					
						
							|  |  |  |  * Minio Cloud Storage, (C) 2016 Minio, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-26 03:58:29 +08:00
										 |  |  | import ( | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	"context" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 	"github.com/minio/minio/cmd/logger" | 
					
						
							| 
									
										
										
										
											2017-11-26 03:58:29 +08:00
										 |  |  | 	"github.com/skyrings/skyring-common/tools/uuid" | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Checks on GetObject arguments, bucket and object.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkGetObjArgs(ctx context.Context, bucket, object string) error { | 
					
						
							|  |  |  | 	return checkBucketAndObjectNames(ctx, bucket, object) | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks on DeleteObject arguments, bucket and object.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkDelObjArgs(ctx context.Context, bucket, object string) error { | 
					
						
							|  |  |  | 	return checkBucketAndObjectNames(ctx, bucket, object) | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks bucket and object name validity, returns nil if both are valid.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkBucketAndObjectNames(ctx context.Context, bucket, object string) error { | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	// Verify if bucket is valid.
 | 
					
						
							|  |  |  | 	if !IsValidBucketName(bucket) { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		logger.LogIf(ctx, BucketNameInvalid{Bucket: bucket}) | 
					
						
							|  |  |  | 		return BucketNameInvalid{Bucket: bucket} | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Verify if object is valid.
 | 
					
						
							| 
									
										
										
										
											2018-01-30 10:43:13 +08:00
										 |  |  | 	if len(object) == 0 { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		logger.LogIf(ctx, ObjectNameInvalid{Bucket: bucket, Object: object}) | 
					
						
							|  |  |  | 		return ObjectNameInvalid{Bucket: bucket, Object: object} | 
					
						
							| 
									
										
										
										
											2018-01-30 10:43:13 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if !IsValidObjectPrefix(object) { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		logger.LogIf(ctx, ObjectNameInvalid{Bucket: bucket, Object: object}) | 
					
						
							|  |  |  | 		return ObjectNameInvalid{Bucket: bucket, Object: object} | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for all ListObjects arguments validity.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkListObjsArgs(ctx context.Context, bucket, prefix, marker, delimiter string, obj ObjectLayer) error { | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	// Verify if bucket exists before validating object name.
 | 
					
						
							|  |  |  | 	// This is done on purpose since the order of errors is
 | 
					
						
							|  |  |  | 	// important here bucket does not exist error should
 | 
					
						
							|  |  |  | 	// happen before we return an error for invalid object name.
 | 
					
						
							|  |  |  | 	// FIXME: should be moved to handler layer.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 	if err := checkBucketExist(ctx, bucket, obj); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Validates object prefix validity after bucket exists.
 | 
					
						
							|  |  |  | 	if !IsValidObjectPrefix(prefix) { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		logger.LogIf(ctx, ObjectNameInvalid{ | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 			Bucket: bucket, | 
					
						
							|  |  |  | 			Object: prefix, | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		return ObjectNameInvalid{ | 
					
						
							|  |  |  | 			Bucket: bucket, | 
					
						
							|  |  |  | 			Object: prefix, | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Verify if delimiter is anything other than '/', which we do not support.
 | 
					
						
							|  |  |  | 	if delimiter != "" && delimiter != slashSeparator { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		logger.LogIf(ctx, UnsupportedDelimiter{ | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 			Delimiter: delimiter, | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		return UnsupportedDelimiter{ | 
					
						
							|  |  |  | 			Delimiter: delimiter, | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Verify if marker has prefix.
 | 
					
						
							| 
									
										
										
										
											2017-02-04 15:27:50 +08:00
										 |  |  | 	if marker != "" && !hasPrefix(marker, prefix) { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		logger.LogIf(ctx, InvalidMarkerPrefixCombination{ | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 			Marker: marker, | 
					
						
							|  |  |  | 			Prefix: prefix, | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		return InvalidMarkerPrefixCombination{ | 
					
						
							|  |  |  | 			Marker: marker, | 
					
						
							|  |  |  | 			Prefix: prefix, | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for all ListMultipartUploads arguments validity.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkListMultipartArgs(ctx context.Context, bucket, prefix, keyMarker, uploadIDMarker, delimiter string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	if err := checkListObjsArgs(ctx, bucket, prefix, keyMarker, delimiter, obj); err != nil { | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if uploadIDMarker != "" { | 
					
						
							| 
									
										
										
										
											2017-02-04 15:27:50 +08:00
										 |  |  | 		if hasSuffix(keyMarker, slashSeparator) { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			logger.LogIf(ctx, InvalidUploadIDKeyCombination{ | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 				UploadIDMarker: uploadIDMarker, | 
					
						
							|  |  |  | 				KeyMarker:      keyMarker, | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 			return InvalidUploadIDKeyCombination{ | 
					
						
							|  |  |  | 				UploadIDMarker: uploadIDMarker, | 
					
						
							|  |  |  | 				KeyMarker:      keyMarker, | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		id, err := uuid.Parse(uploadIDMarker) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 			logger.LogIf(ctx, err) | 
					
						
							|  |  |  | 			return err | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if id.IsZero() { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 			logger.LogIf(ctx, MalformedUploadID{ | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 				UploadID: uploadIDMarker, | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return MalformedUploadID{ | 
					
						
							|  |  |  | 				UploadID: uploadIDMarker, | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for NewMultipartUpload arguments validity, also validates if bucket exists.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkNewMultipartArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	return checkObjectArgs(ctx, bucket, object, obj) | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for PutObjectPart arguments validity, also validates if bucket exists.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkPutObjectPartArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	return checkObjectArgs(ctx, bucket, object, obj) | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for ListParts arguments validity, also validates if bucket exists.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkListPartsArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	return checkObjectArgs(ctx, bucket, object, obj) | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for CompleteMultipartUpload arguments validity, also validates if bucket exists.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkCompleteMultipartArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	return checkObjectArgs(ctx, bucket, object, obj) | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for AbortMultipartUpload arguments validity, also validates if bucket exists.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkAbortMultipartArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	return checkObjectArgs(ctx, bucket, object, obj) | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-10 07:19:30 +08:00
										 |  |  | // Checks Object arguments validity, also validates if bucket exists.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkObjectArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	// Verify if bucket exists before validating object name.
 | 
					
						
							|  |  |  | 	// This is done on purpose since the order of errors is
 | 
					
						
							|  |  |  | 	// important here bucket does not exist error should
 | 
					
						
							|  |  |  | 	// happen before we return an error for invalid object name.
 | 
					
						
							|  |  |  | 	// FIXME: should be moved to handler layer.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 	if err := checkBucketExist(ctx, bucket, obj); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Validates object name validity after bucket exists.
 | 
					
						
							|  |  |  | 	if !IsValidObjectName(object) { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		logger.LogIf(ctx, ObjectNameInvalid{ | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 			Bucket: bucket, | 
					
						
							|  |  |  | 			Object: object, | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return ObjectNameInvalid{ | 
					
						
							|  |  |  | 			Bucket: bucket, | 
					
						
							|  |  |  | 			Object: object, | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-10 07:19:30 +08:00
										 |  |  | // Checks for PutObject arguments validity, also validates if bucket exists.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkPutObjectArgs(ctx context.Context, bucket, object string, obj ObjectLayer, size int64) error { | 
					
						
							| 
									
										
										
										
											2018-02-10 07:19:30 +08:00
										 |  |  | 	// Verify if bucket exists before validating object name.
 | 
					
						
							|  |  |  | 	// This is done on purpose since the order of errors is
 | 
					
						
							|  |  |  | 	// important here bucket does not exist error should
 | 
					
						
							|  |  |  | 	// happen before we return an error for invalid object name.
 | 
					
						
							|  |  |  | 	// FIXME: should be moved to handler layer.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 	if err := checkBucketExist(ctx, bucket, obj); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2018-02-10 07:19:30 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(object) == 0 || | 
					
						
							|  |  |  | 		hasPrefix(object, slashSeparator) || | 
					
						
							|  |  |  | 		(hasSuffix(object, slashSeparator) && size != 0) || | 
					
						
							|  |  |  | 		!IsValidObjectPrefix(object) { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		return ObjectNameInvalid{ | 
					
						
							|  |  |  | 			Bucket: bucket, | 
					
						
							|  |  |  | 			Object: object, | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-02-10 07:19:30 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | // Checks whether bucket exists and returns appropriate error if not.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func checkBucketExist(ctx context.Context, bucket string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	_, err := obj.GetBucketInfo(ctx, bucket) | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2018-04-11 00:36:37 +08:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } |