| 
									
										
										
										
											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-02-04 15:27:50 +08:00
										 |  |  | import "github.com/skyrings/skyring-common/tools/uuid" | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Checks on GetObject arguments, bucket and object.
 | 
					
						
							|  |  |  | func checkGetObjArgs(bucket, object string) error { | 
					
						
							|  |  |  | 	return checkBucketAndObjectNames(bucket, object) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks on DeleteObject arguments, bucket and object.
 | 
					
						
							|  |  |  | func checkDelObjArgs(bucket, object string) error { | 
					
						
							|  |  |  | 	return checkBucketAndObjectNames(bucket, object) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks bucket and object name validity, returns nil if both are valid.
 | 
					
						
							|  |  |  | func checkBucketAndObjectNames(bucket, object string) error { | 
					
						
							|  |  |  | 	// Verify if bucket is valid.
 | 
					
						
							|  |  |  | 	if !IsValidBucketName(bucket) { | 
					
						
							|  |  |  | 		return traceError(BucketNameInvalid{Bucket: bucket}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Verify if object is valid.
 | 
					
						
							|  |  |  | 	if !IsValidObjectName(object) { | 
					
						
							|  |  |  | 		return traceError(ObjectNameInvalid{Bucket: bucket, Object: object}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for all ListObjects arguments validity.
 | 
					
						
							|  |  |  | func checkListObjsArgs(bucket, prefix, marker, delimiter string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	// 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.
 | 
					
						
							|  |  |  | 	if err := checkBucketExist(bucket, obj); err != nil { | 
					
						
							|  |  |  | 		return traceError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Validates object prefix validity after bucket exists.
 | 
					
						
							|  |  |  | 	if !IsValidObjectPrefix(prefix) { | 
					
						
							|  |  |  | 		return traceError(ObjectNameInvalid{ | 
					
						
							|  |  |  | 			Bucket: bucket, | 
					
						
							|  |  |  | 			Object: prefix, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Verify if delimiter is anything other than '/', which we do not support.
 | 
					
						
							|  |  |  | 	if delimiter != "" && delimiter != slashSeparator { | 
					
						
							|  |  |  | 		return traceError(UnsupportedDelimiter{ | 
					
						
							|  |  |  | 			Delimiter: delimiter, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Verify if marker has prefix.
 | 
					
						
							| 
									
										
										
										
											2017-02-04 15:27:50 +08:00
										 |  |  | 	if marker != "" && !hasPrefix(marker, prefix) { | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 		return traceError(InvalidMarkerPrefixCombination{ | 
					
						
							|  |  |  | 			Marker: marker, | 
					
						
							|  |  |  | 			Prefix: prefix, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for all ListMultipartUploads arguments validity.
 | 
					
						
							|  |  |  | func checkListMultipartArgs(bucket, prefix, keyMarker, uploadIDMarker, delimiter string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	if err := checkListObjsArgs(bucket, prefix, keyMarker, delimiter, obj); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if uploadIDMarker != "" { | 
					
						
							| 
									
										
										
										
											2017-02-04 15:27:50 +08:00
										 |  |  | 		if hasSuffix(keyMarker, slashSeparator) { | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 			return traceError(InvalidUploadIDKeyCombination{ | 
					
						
							|  |  |  | 				UploadIDMarker: uploadIDMarker, | 
					
						
							|  |  |  | 				KeyMarker:      keyMarker, | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		id, err := uuid.Parse(uploadIDMarker) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return traceError(err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if id.IsZero() { | 
					
						
							|  |  |  | 			return traceError(MalformedUploadID{ | 
					
						
							|  |  |  | 				UploadID: uploadIDMarker, | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for NewMultipartUpload arguments validity, also validates if bucket exists.
 | 
					
						
							|  |  |  | func checkNewMultipartArgs(bucket, object string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	return checkPutObjectArgs(bucket, object, obj) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for PutObjectPart arguments validity, also validates if bucket exists.
 | 
					
						
							|  |  |  | func checkPutObjectPartArgs(bucket, object string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	return checkPutObjectArgs(bucket, object, obj) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for ListParts arguments validity, also validates if bucket exists.
 | 
					
						
							|  |  |  | func checkListPartsArgs(bucket, object string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	return checkPutObjectArgs(bucket, object, obj) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for CompleteMultipartUpload arguments validity, also validates if bucket exists.
 | 
					
						
							|  |  |  | func checkCompleteMultipartArgs(bucket, object string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	return checkPutObjectArgs(bucket, object, obj) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for AbortMultipartUpload arguments validity, also validates if bucket exists.
 | 
					
						
							|  |  |  | func checkAbortMultipartArgs(bucket, object string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	return checkPutObjectArgs(bucket, object, obj) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks for PutObject arguments validity, also validates if bucket exists.
 | 
					
						
							|  |  |  | func checkPutObjectArgs(bucket, object string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	// 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.
 | 
					
						
							|  |  |  | 	if err := checkBucketExist(bucket, obj); err != nil { | 
					
						
							|  |  |  | 		return traceError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	// Validates object name validity after bucket exists.
 | 
					
						
							|  |  |  | 	if !IsValidObjectName(object) { | 
					
						
							|  |  |  | 		return traceError(ObjectNameInvalid{ | 
					
						
							|  |  |  | 			Bucket: bucket, | 
					
						
							|  |  |  | 			Object: object, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks whether bucket exists and returns appropriate error if not.
 | 
					
						
							|  |  |  | func checkBucketExist(bucket string, obj ObjectLayer) error { | 
					
						
							|  |  |  | 	if !IsValidBucketName(bucket) { | 
					
						
							|  |  |  | 		return BucketNameInvalid{Bucket: bucket} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, err := obj.GetBucketInfo(bucket) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-03-04 02:12:43 +08:00
										 |  |  | 		return errorCause(err) | 
					
						
							| 
									
										
										
										
											2016-12-02 15:15:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } |