api-put-bucket.go (3890B)
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 18 package minio 19 20 import ( 21 "bytes" 22 "context" 23 "encoding/xml" 24 "net/http" 25 26 "github.com/minio/minio-go/v7/pkg/s3utils" 27 ) 28 29 // Bucket operations 30 func (c *Client) makeBucket(ctx context.Context, bucketName string, opts MakeBucketOptions) (err error) { 31 // Validate the input arguments. 32 if err := s3utils.CheckValidBucketNameStrict(bucketName); err != nil { 33 return err 34 } 35 36 err = c.doMakeBucket(ctx, bucketName, opts.Region, opts.ObjectLocking) 37 if err != nil && (opts.Region == "" || opts.Region == "us-east-1") { 38 if resp, ok := err.(ErrorResponse); ok && resp.Code == "AuthorizationHeaderMalformed" && resp.Region != "" { 39 err = c.doMakeBucket(ctx, bucketName, resp.Region, opts.ObjectLocking) 40 } 41 } 42 return err 43 } 44 45 func (c *Client) doMakeBucket(ctx context.Context, bucketName string, location string, objectLockEnabled bool) (err error) { 46 defer func() { 47 // Save the location into cache on a successful makeBucket response. 48 if err == nil { 49 c.bucketLocCache.Set(bucketName, location) 50 } 51 }() 52 53 // If location is empty, treat is a default region 'us-east-1'. 54 if location == "" { 55 location = "us-east-1" 56 // For custom region clients, default 57 // to custom region instead not 'us-east-1'. 58 if c.region != "" { 59 location = c.region 60 } 61 } 62 // PUT bucket request metadata. 63 reqMetadata := requestMetadata{ 64 bucketName: bucketName, 65 bucketLocation: location, 66 } 67 68 if objectLockEnabled { 69 headers := make(http.Header) 70 headers.Add("x-amz-bucket-object-lock-enabled", "true") 71 reqMetadata.customHeader = headers 72 } 73 74 // If location is not 'us-east-1' create bucket location config. 75 if location != "us-east-1" && location != "" { 76 createBucketConfig := createBucketConfiguration{} 77 createBucketConfig.Location = location 78 var createBucketConfigBytes []byte 79 createBucketConfigBytes, err = xml.Marshal(createBucketConfig) 80 if err != nil { 81 return err 82 } 83 reqMetadata.contentMD5Base64 = sumMD5Base64(createBucketConfigBytes) 84 reqMetadata.contentSHA256Hex = sum256Hex(createBucketConfigBytes) 85 reqMetadata.contentBody = bytes.NewReader(createBucketConfigBytes) 86 reqMetadata.contentLength = int64(len(createBucketConfigBytes)) 87 } 88 89 // Execute PUT to create a new bucket. 90 resp, err := c.executeMethod(ctx, http.MethodPut, reqMetadata) 91 defer closeResponse(resp) 92 if err != nil { 93 return err 94 } 95 96 if resp != nil { 97 if resp.StatusCode != http.StatusOK { 98 return httpRespToErrorResponse(resp, bucketName, "") 99 } 100 } 101 102 // Success. 103 return nil 104 } 105 106 // MakeBucketOptions holds all options to tweak bucket creation 107 type MakeBucketOptions struct { 108 // Bucket location 109 Region string 110 // Enable object locking 111 ObjectLocking bool 112 } 113 114 // MakeBucket creates a new bucket with bucketName with a context to control cancellations and timeouts. 115 // 116 // Location is an optional argument, by default all buckets are 117 // created in US Standard Region. 118 // 119 // For Amazon S3 for more supported regions - http://docs.aws.amazon.com/general/latest/gr/rande.html 120 // For Google Cloud Storage for more supported regions - https://cloud.google.com/storage/docs/bucket-locations 121 func (c *Client) MakeBucket(ctx context.Context, bucketName string, opts MakeBucketOptions) (err error) { 122 return c.makeBucket(ctx, bucketName, opts) 123 }