storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/object-api-input-checks.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2016 MinIO, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package cmd 18 19 import ( 20 "context" 21 "runtime" 22 "strings" 23 24 "github.com/google/uuid" 25 "github.com/minio/minio-go/v7/pkg/s3utils" 26 27 "storj.io/minio/cmd/logger" 28 ) 29 30 // Checks on GetObject arguments, bucket and object. 31 func checkGetObjArgs(ctx context.Context, bucket, object string) error { 32 return checkBucketAndObjectNames(ctx, bucket, object) 33 } 34 35 // Checks on DeleteObject arguments, bucket and object. 36 func checkDelObjArgs(ctx context.Context, bucket, object string) error { 37 return checkBucketAndObjectNames(ctx, bucket, object) 38 } 39 40 // Checks bucket and object name validity, returns nil if both are valid. 41 func checkBucketAndObjectNames(ctx context.Context, bucket, object string) error { 42 // Verify if bucket is valid. 43 if !isMinioMetaBucketName(bucket) && s3utils.CheckValidBucketName(bucket) != nil { 44 logger.LogIf(ctx, BucketNameInvalid{Bucket: bucket}) 45 return BucketNameInvalid{Bucket: bucket} 46 } 47 // Verify if object is valid. 48 if len(object) == 0 { 49 logger.LogIf(ctx, ObjectNameInvalid{Bucket: bucket, Object: object}) 50 return ObjectNameInvalid{Bucket: bucket, Object: object} 51 } 52 if !IsValidObjectPrefix(object) { 53 logger.LogIf(ctx, ObjectNameInvalid{Bucket: bucket, Object: object}) 54 return ObjectNameInvalid{Bucket: bucket, Object: object} 55 } 56 if runtime.GOOS == globalWindowsOSName && strings.Contains(object, "\\") { 57 // Objects cannot be contain \ in Windows and is listed as `Characters to Avoid`. 58 return ObjectNameInvalid{Bucket: bucket, Object: object} 59 } 60 return nil 61 } 62 63 // Checks for all ListObjects arguments validity. 64 func checkListObjsArgs(ctx context.Context, bucket, prefix, marker string, obj getBucketInfoI) error { 65 // Verify if bucket exists before validating object name. 66 // This is done on purpose since the order of errors is 67 // important here bucket does not exist error should 68 // happen before we return an error for invalid object name. 69 // FIXME: should be moved to handler layer. 70 if err := checkBucketExist(ctx, bucket, obj); err != nil { 71 return err 72 } 73 // Validates object prefix validity after bucket exists. 74 if !IsValidObjectPrefix(prefix) { 75 logger.LogIf(ctx, ObjectNameInvalid{ 76 Bucket: bucket, 77 Object: prefix, 78 }) 79 return ObjectNameInvalid{ 80 Bucket: bucket, 81 Object: prefix, 82 } 83 } 84 // Verify if marker has prefix. 85 if marker != "" && !HasPrefix(marker, prefix) { 86 logger.LogIf(ctx, InvalidMarkerPrefixCombination{ 87 Marker: marker, 88 Prefix: prefix, 89 }) 90 return InvalidMarkerPrefixCombination{ 91 Marker: marker, 92 Prefix: prefix, 93 } 94 } 95 return nil 96 } 97 98 // Checks for all ListMultipartUploads arguments validity. 99 func checkListMultipartArgs(ctx context.Context, bucket, prefix, keyMarker, uploadIDMarker, delimiter string, obj ObjectLayer) error { 100 if err := checkListObjsArgs(ctx, bucket, prefix, keyMarker, obj); err != nil { 101 return err 102 } 103 if uploadIDMarker != "" { 104 if HasSuffix(keyMarker, SlashSeparator) { 105 106 logger.LogIf(ctx, InvalidUploadIDKeyCombination{ 107 UploadIDMarker: uploadIDMarker, 108 KeyMarker: keyMarker, 109 }) 110 return InvalidUploadIDKeyCombination{ 111 UploadIDMarker: uploadIDMarker, 112 KeyMarker: keyMarker, 113 } 114 } 115 if _, err := uuid.Parse(uploadIDMarker); err != nil { 116 logger.LogIf(ctx, err) 117 return MalformedUploadID{ 118 UploadID: uploadIDMarker, 119 } 120 } 121 } 122 return nil 123 } 124 125 // Checks for NewMultipartUpload arguments validity, also validates if bucket exists. 126 func checkNewMultipartArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { 127 return checkObjectArgs(ctx, bucket, object, obj) 128 } 129 130 // Checks for PutObjectPart arguments validity, also validates if bucket exists. 131 func checkPutObjectPartArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { 132 return checkObjectArgs(ctx, bucket, object, obj) 133 } 134 135 // Checks for ListParts arguments validity, also validates if bucket exists. 136 func checkListPartsArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { 137 return checkObjectArgs(ctx, bucket, object, obj) 138 } 139 140 // Checks for CompleteMultipartUpload arguments validity, also validates if bucket exists. 141 func checkCompleteMultipartArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { 142 return checkObjectArgs(ctx, bucket, object, obj) 143 } 144 145 // Checks for AbortMultipartUpload arguments validity, also validates if bucket exists. 146 func checkAbortMultipartArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { 147 return checkObjectArgs(ctx, bucket, object, obj) 148 } 149 150 // Checks Object arguments validity, also validates if bucket exists. 151 func checkObjectArgs(ctx context.Context, bucket, object string, obj ObjectLayer) error { 152 // Verify if bucket exists before validating object name. 153 // This is done on purpose since the order of errors is 154 // important here bucket does not exist error should 155 // happen before we return an error for invalid object name. 156 // FIXME: should be moved to handler layer. 157 if err := checkBucketExist(ctx, bucket, obj); err != nil { 158 return err 159 } 160 161 if err := checkObjectNameForLengthAndSlash(bucket, object); err != nil { 162 return err 163 } 164 165 // Validates object name validity after bucket exists. 166 if !IsValidObjectName(object) { 167 return ObjectNameInvalid{ 168 Bucket: bucket, 169 Object: object, 170 } 171 } 172 173 return nil 174 } 175 176 // Checks for PutObject arguments validity, also validates if bucket exists. 177 func checkPutObjectArgs(ctx context.Context, bucket, object string, obj getBucketInfoI) error { 178 // Verify if bucket exists before validating object name. 179 // This is done on purpose since the order of errors is 180 // important here bucket does not exist error should 181 // happen before we return an error for invalid object name. 182 // FIXME: should be moved to handler layer. 183 if err := checkBucketExist(ctx, bucket, obj); err != nil { 184 return err 185 } 186 187 if err := checkObjectNameForLengthAndSlash(bucket, object); err != nil { 188 return err 189 } 190 if len(object) == 0 || 191 !IsValidObjectPrefix(object) { 192 return ObjectNameInvalid{ 193 Bucket: bucket, 194 Object: object, 195 } 196 } 197 return nil 198 } 199 200 type getBucketInfoI interface { 201 GetBucketInfo(ctx context.Context, bucket string) (bucketInfo BucketInfo, err error) 202 } 203 204 // Checks whether bucket exists and returns appropriate error if not. 205 func checkBucketExist(ctx context.Context, bucket string, obj getBucketInfoI) error { 206 _, err := obj.GetBucketInfo(ctx, bucket) 207 if err != nil { 208 return err 209 } 210 return nil 211 }