api-stat.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * MinIO Go Library for Amazon S3 Compatible Cloud Storage
  3. * Copyright 2015-2020 MinIO, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package minio
  18. import (
  19. "context"
  20. "net/http"
  21. "net/url"
  22. "github.com/minio/minio-go/v7/pkg/s3utils"
  23. )
  24. // BucketExists verifies if bucket exists and you have permission to access it. Allows for a Context to
  25. // control cancellations and timeouts.
  26. func (c Client) BucketExists(ctx context.Context, bucketName string) (bool, error) {
  27. // Input validation.
  28. if err := s3utils.CheckValidBucketName(bucketName); err != nil {
  29. return false, err
  30. }
  31. // Execute HEAD on bucketName.
  32. resp, err := c.executeMethod(ctx, http.MethodHead, requestMetadata{
  33. bucketName: bucketName,
  34. contentSHA256Hex: emptySHA256Hex,
  35. })
  36. defer closeResponse(resp)
  37. if err != nil {
  38. if ToErrorResponse(err).Code == "NoSuchBucket" {
  39. return false, nil
  40. }
  41. return false, err
  42. }
  43. if resp != nil {
  44. resperr := httpRespToErrorResponse(resp, bucketName, "")
  45. if ToErrorResponse(resperr).Code == "NoSuchBucket" {
  46. return false, nil
  47. }
  48. if resp.StatusCode != http.StatusOK {
  49. return false, httpRespToErrorResponse(resp, bucketName, "")
  50. }
  51. }
  52. return true, nil
  53. }
  54. // StatObject verifies if object exists and you have permission to access.
  55. func (c Client) StatObject(ctx context.Context, bucketName, objectName string, opts StatObjectOptions) (ObjectInfo, error) {
  56. // Input validation.
  57. if err := s3utils.CheckValidBucketName(bucketName); err != nil {
  58. return ObjectInfo{}, err
  59. }
  60. if err := s3utils.CheckValidObjectName(objectName); err != nil {
  61. return ObjectInfo{}, err
  62. }
  63. return c.statObject(ctx, bucketName, objectName, opts)
  64. }
  65. // Lower level API for statObject supporting pre-conditions and range headers.
  66. func (c Client) statObject(ctx context.Context, bucketName, objectName string, opts StatObjectOptions) (ObjectInfo, error) {
  67. // Input validation.
  68. if err := s3utils.CheckValidBucketName(bucketName); err != nil {
  69. return ObjectInfo{}, err
  70. }
  71. if err := s3utils.CheckValidObjectName(objectName); err != nil {
  72. return ObjectInfo{}, err
  73. }
  74. headers := opts.Header()
  75. if opts.Internal.ReplicationDeleteMarker {
  76. headers.Set(minIOBucketReplicationDeleteMarker, "true")
  77. }
  78. urlValues := make(url.Values)
  79. if opts.VersionID != "" {
  80. urlValues.Set("versionId", opts.VersionID)
  81. }
  82. // Execute HEAD on objectName.
  83. resp, err := c.executeMethod(ctx, http.MethodHead, requestMetadata{
  84. bucketName: bucketName,
  85. objectName: objectName,
  86. queryValues: urlValues,
  87. contentSHA256Hex: emptySHA256Hex,
  88. customHeader: headers,
  89. })
  90. defer closeResponse(resp)
  91. if err != nil {
  92. return ObjectInfo{}, err
  93. }
  94. if resp != nil {
  95. deleteMarker := resp.Header.Get(amzDeleteMarker) == "true"
  96. if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent {
  97. if resp.StatusCode == http.StatusMethodNotAllowed && opts.VersionID != "" && deleteMarker {
  98. errResp := ErrorResponse{
  99. StatusCode: resp.StatusCode,
  100. Code: "MethodNotAllowed",
  101. Message: "The specified method is not allowed against this resource.",
  102. BucketName: bucketName,
  103. Key: objectName,
  104. }
  105. return ObjectInfo{
  106. VersionID: resp.Header.Get(amzVersionID),
  107. IsDeleteMarker: deleteMarker,
  108. }, errResp
  109. }
  110. return ObjectInfo{
  111. VersionID: resp.Header.Get(amzVersionID),
  112. IsDeleteMarker: deleteMarker,
  113. }, httpRespToErrorResponse(resp, bucketName, objectName)
  114. }
  115. }
  116. return ToObjectInfo(bucketName, objectName, resp.Header)
  117. }