github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/object-api-datatypes.go (about) 1 // Copyright (c) 2015-2021 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package cmd 19 20 import ( 21 "io" 22 "math" 23 "net/http" 24 "time" 25 26 "github.com/dustin/go-humanize" 27 "github.com/minio/madmin-go/v3" 28 "github.com/minio/minio/internal/bucket/replication" 29 "github.com/minio/minio/internal/hash" 30 "github.com/minio/minio/internal/logger" 31 ) 32 33 //go:generate msgp -file $GOFILE -io=false -tests=false -unexported=false 34 35 // BackendType - represents different backend types. 36 type BackendType int 37 38 // Enum for different backend types. 39 const ( 40 Unknown = BackendType(madmin.Unknown) 41 // Filesystem backend. 42 BackendFS = BackendType(madmin.FS) 43 // Multi disk BackendErasure (single, distributed) backend. 44 BackendErasure = BackendType(madmin.Erasure) 45 // Add your own backend. 46 ) 47 48 // StorageInfo - represents total capacity of underlying storage. 49 type StorageInfo = madmin.StorageInfo 50 51 // objectHistogramInterval is an interval that will be 52 // used to report the histogram of objects data sizes 53 type objectHistogramInterval struct { 54 name string 55 start, end int64 56 } 57 58 const ( 59 // dataUsageBucketLenV1 must be length of ObjectsHistogramIntervalsV1 60 dataUsageBucketLenV1 = 7 61 // dataUsageBucketLen must be length of ObjectsHistogramIntervals 62 dataUsageBucketLen = 11 63 dataUsageVersionLen = 7 64 ) 65 66 // ObjectsHistogramIntervalsV1 is the list of all intervals 67 // of object sizes to be included in objects histogram(V1). 68 var ObjectsHistogramIntervalsV1 = [dataUsageBucketLenV1]objectHistogramInterval{ 69 {"LESS_THAN_1024_B", 0, humanize.KiByte - 1}, 70 {"BETWEEN_1024B_AND_1_MB", humanize.KiByte, humanize.MiByte - 1}, 71 {"BETWEEN_1_MB_AND_10_MB", humanize.MiByte, humanize.MiByte*10 - 1}, 72 {"BETWEEN_10_MB_AND_64_MB", humanize.MiByte * 10, humanize.MiByte*64 - 1}, 73 {"BETWEEN_64_MB_AND_128_MB", humanize.MiByte * 64, humanize.MiByte*128 - 1}, 74 {"BETWEEN_128_MB_AND_512_MB", humanize.MiByte * 128, humanize.MiByte*512 - 1}, 75 {"GREATER_THAN_512_MB", humanize.MiByte * 512, math.MaxInt64}, 76 } 77 78 // ObjectsHistogramIntervals is the list of all intervals 79 // of object sizes to be included in objects histogram. 80 // Note: this histogram expands 1024B-1MB to incl. 1024B-64KB, 64KB-256KB, 256KB-512KB and 512KB-1MiB 81 var ObjectsHistogramIntervals = [dataUsageBucketLen]objectHistogramInterval{ 82 {"LESS_THAN_1024_B", 0, humanize.KiByte - 1}, 83 {"BETWEEN_1024_B_AND_64_KB", humanize.KiByte, 64*humanize.KiByte - 1}, // not exported, for support use only 84 {"BETWEEN_64_KB_AND_256_KB", 64 * humanize.KiByte, 256*humanize.KiByte - 1}, // not exported, for support use only 85 {"BETWEEN_256_KB_AND_512_KB", 256 * humanize.KiByte, 512*humanize.KiByte - 1}, // not exported, for support use only 86 {"BETWEEN_512_KB_AND_1_MB", 512 * humanize.KiByte, humanize.MiByte - 1}, // not exported, for support use only 87 {"BETWEEN_1024B_AND_1_MB", humanize.KiByte, humanize.MiByte - 1}, 88 {"BETWEEN_1_MB_AND_10_MB", humanize.MiByte, humanize.MiByte*10 - 1}, 89 {"BETWEEN_10_MB_AND_64_MB", humanize.MiByte * 10, humanize.MiByte*64 - 1}, 90 {"BETWEEN_64_MB_AND_128_MB", humanize.MiByte * 64, humanize.MiByte*128 - 1}, 91 {"BETWEEN_128_MB_AND_512_MB", humanize.MiByte * 128, humanize.MiByte*512 - 1}, 92 {"GREATER_THAN_512_MB", humanize.MiByte * 512, math.MaxInt64}, 93 } 94 95 // ObjectsVersionCountIntervals is the list of all intervals 96 // of object version count to be included in objects histogram. 97 var ObjectsVersionCountIntervals = [dataUsageVersionLen]objectHistogramInterval{ 98 {"UNVERSIONED", 0, 0}, 99 {"SINGLE_VERSION", 1, 1}, 100 {"BETWEEN_2_AND_10", 2, 9}, 101 {"BETWEEN_10_AND_100", 10, 99}, 102 {"BETWEEN_100_AND_1000", 100, 999}, 103 {"BETWEEN_1000_AND_10000", 1000, 9999}, 104 {"GREATER_THAN_10000", 10000, math.MaxInt64}, 105 } 106 107 // BucketInfo - represents bucket metadata. 108 type BucketInfo struct { 109 // Name of the bucket. 110 Name string 111 112 // Date and time when the bucket was created. 113 Created time.Time 114 Deleted time.Time 115 116 // Bucket features enabled 117 Versioning, ObjectLocking bool 118 } 119 120 // ObjectInfo - represents object metadata. 121 type ObjectInfo struct { 122 // Name of the bucket. 123 Bucket string 124 125 // Name of the object. 126 Name string 127 128 // Date and time when the object was last modified. 129 ModTime time.Time 130 131 // Total object size. 132 Size int64 133 134 // Actual size is the real size of the object uploaded by client. 135 ActualSize *int64 136 137 // IsDir indicates if the object is prefix. 138 IsDir bool 139 140 // Hex encoded unique entity tag of the object. 141 ETag string 142 143 // Version ID of this object. 144 VersionID string 145 146 // IsLatest indicates if this is the latest current version 147 // latest can be true for delete marker or a version. 148 IsLatest bool 149 150 // DeleteMarker indicates if the versionId corresponds 151 // to a delete marker on an object. 152 DeleteMarker bool 153 154 // Transitioned object information 155 TransitionedObject TransitionedObject 156 157 // RestoreExpires indicates date a restored object expires 158 RestoreExpires time.Time 159 160 // RestoreOngoing indicates if a restore is in progress 161 RestoreOngoing bool 162 163 // A standard MIME type describing the format of the object. 164 ContentType string 165 166 // Specifies what content encodings have been applied to the object and thus 167 // what decoding mechanisms must be applied to obtain the object referenced 168 // by the Content-Type header field. 169 ContentEncoding string 170 171 // Date and time at which the object is no longer able to be cached 172 Expires time.Time 173 174 // Cache-Control - Specifies caching behavior along the request/reply chain 175 CacheControl string 176 177 // Specify object storage class 178 StorageClass string 179 180 ReplicationStatusInternal string 181 ReplicationStatus replication.StatusType 182 // User-Defined metadata 183 UserDefined map[string]string 184 185 // User-Defined object tags 186 UserTags string 187 188 // List of individual parts, maximum size of upto 10,000 189 Parts []ObjectPartInfo `json:"-"` 190 191 // Implements writer and reader used by CopyObject API 192 Writer io.WriteCloser `json:"-" msg:"-"` 193 Reader *hash.Reader `json:"-" msg:"-"` 194 PutObjReader *PutObjReader `json:"-" msg:"-"` 195 196 metadataOnly bool 197 versionOnly bool // adds a new version, only used by CopyObject 198 keyRotation bool 199 200 // Date and time when the object was last accessed. 201 AccTime time.Time 202 203 Legacy bool // indicates object on disk is in legacy data format 204 205 // internal representation of version purge status 206 VersionPurgeStatusInternal string 207 VersionPurgeStatus VersionPurgeStatusType 208 209 replicationDecision string // internal representation of replication decision for use by DeleteObject handler 210 // The total count of all versions of this object 211 NumVersions int 212 // The modtime of the successor object version if any 213 SuccessorModTime time.Time 214 215 // Checksums added on upload. 216 // Encoded, maybe encrypted. 217 Checksum []byte 218 219 // Inlined 220 Inlined bool 221 222 DataBlocks int 223 ParityBlocks int 224 } 225 226 // ExpiresStr returns a stringified version of Expires header in http.TimeFormat 227 func (o ObjectInfo) ExpiresStr() string { 228 var expires string 229 if !o.Expires.IsZero() { 230 expires = o.Expires.UTC().Format(http.TimeFormat) 231 } 232 return expires 233 } 234 235 // ArchiveInfo returns any saved zip archive meta information. 236 // It will be decrypted if needed. 237 func (o *ObjectInfo) ArchiveInfo() []byte { 238 if len(o.UserDefined) == 0 { 239 return nil 240 } 241 z, ok := o.UserDefined[archiveInfoMetadataKey] 242 if !ok { 243 return nil 244 } 245 data := []byte(z) 246 if v, ok := o.UserDefined[archiveTypeMetadataKey]; ok && v == archiveTypeEnc { 247 decrypted, err := o.metadataDecrypter()(archiveTypeEnc, data) 248 if err != nil { 249 logger.LogIf(GlobalContext, err) 250 return nil 251 } 252 data = decrypted 253 } 254 return data 255 } 256 257 // Clone - Returns a cloned copy of current objectInfo 258 func (o *ObjectInfo) Clone() (cinfo ObjectInfo) { 259 cinfo = ObjectInfo{ 260 Bucket: o.Bucket, 261 Name: o.Name, 262 ModTime: o.ModTime, 263 Size: o.Size, 264 IsDir: o.IsDir, 265 ETag: o.ETag, 266 VersionID: o.VersionID, 267 IsLatest: o.IsLatest, 268 DeleteMarker: o.DeleteMarker, 269 TransitionedObject: o.TransitionedObject, 270 RestoreExpires: o.RestoreExpires, 271 RestoreOngoing: o.RestoreOngoing, 272 ContentType: o.ContentType, 273 ContentEncoding: o.ContentEncoding, 274 Expires: o.Expires, 275 StorageClass: o.StorageClass, 276 ReplicationStatus: o.ReplicationStatus, 277 UserTags: o.UserTags, 278 Parts: o.Parts, 279 Writer: o.Writer, 280 Reader: o.Reader, 281 PutObjReader: o.PutObjReader, 282 metadataOnly: o.metadataOnly, 283 versionOnly: o.versionOnly, 284 keyRotation: o.keyRotation, 285 AccTime: o.AccTime, 286 Legacy: o.Legacy, 287 VersionPurgeStatus: o.VersionPurgeStatus, 288 NumVersions: o.NumVersions, 289 SuccessorModTime: o.SuccessorModTime, 290 ReplicationStatusInternal: o.ReplicationStatusInternal, 291 VersionPurgeStatusInternal: o.VersionPurgeStatusInternal, 292 } 293 cinfo.UserDefined = make(map[string]string, len(o.UserDefined)) 294 for k, v := range o.UserDefined { 295 cinfo.UserDefined[k] = v 296 } 297 return cinfo 298 } 299 300 func (o ObjectInfo) tierStats() tierStats { 301 ts := tierStats{ 302 TotalSize: uint64(o.Size), 303 NumVersions: 1, 304 } 305 // the current version of an object is accounted towards objects count 306 if o.IsLatest { 307 ts.NumObjects = 1 308 } 309 return ts 310 } 311 312 // ToObjectInfo converts a replication object info to a partial ObjectInfo 313 // do not rely on this function to give you correct ObjectInfo, this 314 // function is merely and optimization. 315 func (ri ReplicateObjectInfo) ToObjectInfo() ObjectInfo { 316 return ObjectInfo{ 317 Name: ri.Name, 318 Bucket: ri.Bucket, 319 VersionID: ri.VersionID, 320 ModTime: ri.ModTime, 321 UserTags: ri.UserTags, 322 Size: ri.Size, 323 ActualSize: &ri.ActualSize, 324 ReplicationStatus: ri.ReplicationStatus, 325 ReplicationStatusInternal: ri.ReplicationStatusInternal, 326 VersionPurgeStatus: ri.VersionPurgeStatus, 327 VersionPurgeStatusInternal: ri.VersionPurgeStatusInternal, 328 DeleteMarker: true, 329 UserDefined: map[string]string{}, 330 } 331 } 332 333 // ReplicateObjectInfo represents object info to be replicated 334 type ReplicateObjectInfo struct { 335 Name string 336 Bucket string 337 VersionID string 338 ETag string 339 Size int64 340 ActualSize int64 341 ModTime time.Time 342 UserTags string 343 SSEC bool 344 ReplicationStatus replication.StatusType 345 ReplicationStatusInternal string 346 VersionPurgeStatusInternal string 347 VersionPurgeStatus VersionPurgeStatusType 348 ReplicationState ReplicationState 349 DeleteMarker bool 350 351 OpType replication.Type 352 EventType string 353 RetryCount uint32 354 ResetID string 355 Dsc ReplicateDecision 356 ExistingObjResync ResyncDecision 357 TargetArn string 358 TargetStatuses map[string]replication.StatusType 359 TargetPurgeStatuses map[string]VersionPurgeStatusType 360 ReplicationTimestamp time.Time 361 } 362 363 // MultipartInfo captures metadata information about the uploadId 364 // this data structure is used primarily for some internal purposes 365 // for verifying upload type such as was the upload 366 // - encrypted 367 // - compressed 368 type MultipartInfo struct { 369 // Name of the bucket. 370 Bucket string 371 372 // Name of the object. 373 Object string 374 375 // Upload ID identifying the multipart upload whose parts are being listed. 376 UploadID string 377 378 // Date and time at which the multipart upload was initiated. 379 Initiated time.Time 380 381 // Any metadata set during InitMultipartUpload, including encryption headers. 382 UserDefined map[string]string 383 } 384 385 // ListPartsInfo - represents list of all parts. 386 type ListPartsInfo struct { 387 // Name of the bucket. 388 Bucket string 389 390 // Name of the object. 391 Object string 392 393 // Upload ID identifying the multipart upload whose parts are being listed. 394 UploadID string 395 396 // The class of storage used to store the object. 397 StorageClass string 398 399 // Part number after which listing begins. 400 PartNumberMarker int 401 402 // When a list is truncated, this element specifies the last part in the list, 403 // as well as the value to use for the part-number-marker request parameter 404 // in a subsequent request. 405 NextPartNumberMarker int 406 407 // Maximum number of parts that were allowed in the response. 408 MaxParts int 409 410 // Indicates whether the returned list of parts is truncated. 411 IsTruncated bool 412 413 // List of all parts. 414 Parts []PartInfo 415 416 // Any metadata set during InitMultipartUpload, including encryption headers. 417 UserDefined map[string]string 418 419 // ChecksumAlgorithm if set 420 ChecksumAlgorithm string 421 } 422 423 // Lookup - returns if uploadID is valid 424 func (lm ListMultipartsInfo) Lookup(uploadID string) bool { 425 for _, upload := range lm.Uploads { 426 if upload.UploadID == uploadID { 427 return true 428 } 429 } 430 return false 431 } 432 433 // ListMultipartsInfo - represents bucket resources for incomplete multipart uploads. 434 type ListMultipartsInfo struct { 435 // Together with upload-id-marker, this parameter specifies the multipart upload 436 // after which listing should begin. 437 KeyMarker string 438 439 // Together with key-marker, specifies the multipart upload after which listing 440 // should begin. If key-marker is not specified, the upload-id-marker parameter 441 // is ignored. 442 UploadIDMarker string 443 444 // When a list is truncated, this element specifies the value that should be 445 // used for the key-marker request parameter in a subsequent request. 446 NextKeyMarker string 447 448 // When a list is truncated, this element specifies the value that should be 449 // used for the upload-id-marker request parameter in a subsequent request. 450 NextUploadIDMarker string 451 452 // Maximum number of multipart uploads that could have been included in the 453 // response. 454 MaxUploads int 455 456 // Indicates whether the returned list of multipart uploads is truncated. A 457 // value of true indicates that the list was truncated. The list can be truncated 458 // if the number of multipart uploads exceeds the limit allowed or specified 459 // by max uploads. 460 IsTruncated bool 461 462 // List of all pending uploads. 463 Uploads []MultipartInfo 464 465 // When a prefix is provided in the request, The result contains only keys 466 // starting with the specified prefix. 467 Prefix string 468 469 // A character used to truncate the object prefixes. 470 // NOTE: only supported delimiter is '/'. 471 Delimiter string 472 473 // CommonPrefixes contains all (if there are any) keys between Prefix and the 474 // next occurrence of the string specified by delimiter. 475 CommonPrefixes []string 476 477 EncodingType string // Not supported yet. 478 } 479 480 // TransitionedObject transitioned object tier and status. 481 type TransitionedObject struct { 482 Name string 483 VersionID string 484 Tier string 485 FreeVersion bool 486 Status string 487 } 488 489 // DeletedObjectInfo - container for list objects versions deleted objects. 490 type DeletedObjectInfo struct { 491 // Name of the bucket. 492 Bucket string 493 494 // Name of the object. 495 Name string 496 497 // Date and time when the object was last modified. 498 ModTime time.Time 499 500 // Version ID of this object. 501 VersionID string 502 503 // Indicates the deleted marker is latest 504 IsLatest bool 505 } 506 507 // ListObjectVersionsInfo - container for list objects versions. 508 type ListObjectVersionsInfo struct { 509 // Indicates whether the returned list objects response is truncated. A 510 // value of true indicates that the list was truncated. The list can be truncated 511 // if the number of objects exceeds the limit allowed or specified 512 // by max keys. 513 IsTruncated bool 514 515 // When response is truncated (the IsTruncated element value in the response is true), 516 // you can use the key name in this field as marker in the subsequent 517 // request to get next set of objects. 518 // 519 // NOTE: AWS S3 returns NextMarker only if you have delimiter request parameter specified, 520 // MinIO always returns NextMarker. 521 NextMarker string 522 523 // NextVersionIDMarker may be set of IsTruncated is true 524 NextVersionIDMarker string 525 526 // List of objects info for this request. 527 Objects []ObjectInfo 528 529 // List of prefixes for this request. 530 Prefixes []string 531 } 532 533 // ListObjectsInfo - container for list objects. 534 type ListObjectsInfo struct { 535 // Indicates whether the returned list objects response is truncated. A 536 // value of true indicates that the list was truncated. The list can be truncated 537 // if the number of objects exceeds the limit allowed or specified 538 // by max keys. 539 IsTruncated bool 540 541 // When response is truncated (the IsTruncated element value in the response is true), 542 // you can use the key name in this field as marker in the subsequent 543 // request to get next set of objects. 544 // 545 // NOTE: AWS S3 returns NextMarker only if you have delimiter request parameter specified, 546 // MinIO always returns NextMarker. 547 NextMarker string 548 549 // List of objects info for this request. 550 Objects []ObjectInfo 551 552 // List of prefixes for this request. 553 Prefixes []string 554 } 555 556 // ListObjectsV2Info - container for list objects version 2. 557 type ListObjectsV2Info struct { 558 // Indicates whether the returned list objects response is truncated. A 559 // value of true indicates that the list was truncated. The list can be truncated 560 // if the number of objects exceeds the limit allowed or specified 561 // by max keys. 562 IsTruncated bool 563 564 // When response is truncated (the IsTruncated element value in the response 565 // is true), you can use the key name in this field as marker in the subsequent 566 // request to get next set of objects. 567 // 568 // NOTE: This element is returned only if you have delimiter request parameter 569 // specified. 570 ContinuationToken string 571 NextContinuationToken string 572 573 // List of objects info for this request. 574 Objects []ObjectInfo 575 576 // List of prefixes for this request. 577 Prefixes []string 578 } 579 580 // PartInfo - represents individual part metadata. 581 type PartInfo struct { 582 // Part number that identifies the part. This is a positive integer between 583 // 1 and 10,000. 584 PartNumber int 585 586 // Date and time at which the part was uploaded. 587 LastModified time.Time 588 589 // Entity tag returned when the part was initially uploaded. 590 ETag string 591 592 // Size in bytes of the part. 593 Size int64 594 595 // Real size of the object uploaded by client. 596 ActualSize int64 597 598 // Checksum values 599 ChecksumCRC32 string 600 ChecksumCRC32C string 601 ChecksumSHA1 string 602 ChecksumSHA256 string 603 } 604 605 // CompletePart - represents the part that was completed, this is sent by the client 606 // during CompleteMultipartUpload request. 607 type CompletePart struct { 608 // Part number identifying the part. This is a positive integer between 1 and 609 // 10,000 610 PartNumber int 611 612 // Entity tag returned when the part was uploaded. 613 ETag string 614 615 // Checksum values. Optional. 616 ChecksumCRC32 string 617 ChecksumCRC32C string 618 ChecksumSHA1 string 619 ChecksumSHA256 string 620 } 621 622 // CompleteMultipartUpload - represents list of parts which are completed, this is sent by the 623 // client during CompleteMultipartUpload request. 624 type CompleteMultipartUpload struct { 625 Parts []CompletePart `xml:"Part"` 626 } 627 628 // NewMultipartUploadResult contains information about a newly created multipart upload. 629 type NewMultipartUploadResult struct { 630 UploadID string 631 ChecksumAlgo string 632 } 633 634 type getObjectAttributesResponse struct { 635 ETag string `xml:",omitempty"` 636 Checksum *objectAttributesChecksum `xml:",omitempty"` 637 ObjectParts *objectAttributesParts `xml:",omitempty"` 638 StorageClass string `xml:",omitempty"` 639 ObjectSize int64 `xml:",omitempty"` 640 } 641 642 type objectAttributesChecksum struct { 643 ChecksumCRC32 string `xml:",omitempty"` 644 ChecksumCRC32C string `xml:",omitempty"` 645 ChecksumSHA1 string `xml:",omitempty"` 646 ChecksumSHA256 string `xml:",omitempty"` 647 } 648 649 type objectAttributesParts struct { 650 IsTruncated bool 651 MaxParts int 652 NextPartNumberMarker int 653 PartNumberMarker int 654 PartsCount int 655 Parts []*objectAttributesPart `xml:"Part"` 656 } 657 658 type objectAttributesPart struct { 659 PartNumber int 660 Size int64 661 ChecksumCRC32 string `xml:",omitempty"` 662 ChecksumCRC32C string `xml:",omitempty"` 663 ChecksumSHA1 string `xml:",omitempty"` 664 ChecksumSHA256 string `xml:",omitempty"` 665 } 666 667 type objectAttributesErrorResponse struct { 668 ArgumentValue *string `xml:"ArgumentValue,omitempty"` 669 ArgumentName *string `xml:"ArgumentName"` 670 APIErrorResponse 671 }