2021-04-19 03:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Copyright (c) 2015-2021 MinIO, Inc.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This file is part of MinIO Object Storage stack
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is free software: you can redistribute it and/or modify
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it under the terms of the GNU Affero General Public License as published by
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Free Software Foundation, either version 3 of the License, or
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (at your option) any later version.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is distributed in the hope that it will be useful
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GNU Affero General Public License for more details.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You should have received a copy of the GNU Affero General Public License
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// along with this program.  If not, see <http://www.gnu.org/licenses/>.
  
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-19 07:23:42 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  cmd  
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2021-03-26 04:57:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 01:24:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-25 14:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/base64" 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"encoding/xml" 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-05 23:18:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-04 12:41:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net/textproto" 
							 
						 
					
						
							
								
									
										
										
											
												accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
   "*":                             true,
   "s3:*":                          true,
   "s3:GetObject":                  true,
   "s3:ListBucket":                 true,
   "s3:PutObject":                  true,
   "s3:CreateBucket":               true,
   "s3:GetBucketLocation":          true,
   "s3:DeleteBucket":               true,
   "s3:DeleteObject":               true,
   "s3:AbortMultipartUpload":       true,
   "s3:ListBucketMultipartUploads": true,
   "s3:ListMultipartUploadParts":   true,
following conditions for "StringEquals" and "StringNotEquals"
   "s3:prefix", "s3:max-keys"
											 
										 
										
											2016-02-04 08:46:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-12 05:26:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"path" 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sort" 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-09 08:36:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
									
										
										
											
												accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
   "*":                             true,
   "s3:*":                          true,
   "s3:GetObject":                  true,
   "s3:ListBucket":                 true,
   "s3:PutObject":                  true,
   "s3:CreateBucket":               true,
   "s3:GetBucketLocation":          true,
   "s3:DeleteBucket":               true,
   "s3:DeleteObject":               true,
   "s3:AbortMultipartUpload":       true,
   "s3:ListBucketMultipartUploads": true,
   "s3:ListMultipartUploadParts":   true,
following conditions for "StringEquals" and "StringNotEquals"
   "s3:prefix", "s3:max-keys"
											 
										 
										
											2016-02-04 08:46:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-12 12:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/google/uuid" 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-22 10:23:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/gorilla/mux" 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-12 03:02:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/madmin-go" 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-15 00:38:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v7/pkg/set" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v7/pkg/tags" 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 00:02:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sse  "github.com/minio/minio/internal/bucket/encryption" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-02 05:59:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectlock  "github.com/minio/minio/internal/bucket/object/lock" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/bucket/replication" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/config/dns" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/crypto" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/event" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/handlers" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/hash" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xhttp  "github.com/minio/minio/internal/http" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/kms" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/logger" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/sync/errgroup" 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-30 12:16:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/pkg/bucket/policy" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									iampolicy  "github.com/minio/pkg/iam/policy" 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
									
										
										
										
											2020-07-22 08:49:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectLockConfig         =  "object-lock.xml" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucketTaggingConfig      =  "tagging.xml" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucketReplicationConfig  =  "replication.xml" 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-05 23:18:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Check if there are buckets on server without corresponding entry in etcd backend and
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// make entries. Here is the general flow
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// - Range over all the available buckets
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// - Check if a bucket has an entry in etcd backend
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// -- If no, make an entry
  
						 
					
						
							
								
									
										
										
										
											2019-12-17 12:30:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// -- If yes, check if the entry matches local IP check if we
  
						 
					
						
							
								
									
										
										
										
											2022-08-27 03:52:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	need to update the entry then proceed to update
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
									
										
										
										
											2019-12-17 12:30:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// -- If yes, check if the IP of entry matches local IP.
  
						 
					
						
							
								
									
										
										
										
											2022-08-27 03:52:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	This means entry is for this instance.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
									
										
										
										
											2019-12-17 12:30:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// -- If IP of the entry doesn't match, this means entry is
  
						 
					
						
							
								
									
										
										
										
											2022-08-27 03:52:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	for another instance. Log an error to console.
  
						 
					
						
							
								
									
										
										
										
											2019-11-10 01:27:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  initFederatorBackend ( buckets  [ ] BucketInfo ,  objLayer  ObjectLayer )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( buckets )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-05 23:18:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 23:49:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Get buckets in the DNS
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dnsBuckets ,  err  :=  globalDNSConfig . List ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  &&  ! IsErrIgnored ( err ,  dns . ErrNoEntriesFound ,  dns . ErrNotImplemented ,  dns . ErrDomainMissing )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 00:30:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logger . LogIf ( GlobalContext ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 23:49:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bucketsSet  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucketsToBeUpdated  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucketsInConflict  :=  set . NewStringSet ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This means that domain is updated, we should update
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// all bucket entries with new domain name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									domainMissing  :=  err  ==  dns . ErrDomainMissing 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 03:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  dnsBuckets  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  bucket  :=  range  buckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketsSet . Add ( bucket . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r ,  ok  :=  dnsBuckets [ bucket . Name ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bucketsToBeUpdated . Add ( bucket . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 03:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! globalDomainIPs . Intersection ( set . CreateStringSet ( getHostsSlice ( r ) ... ) ) . IsEmpty ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  globalDomainIPs . Difference ( set . CreateStringSet ( getHostsSlice ( r ) ... ) ) . IsEmpty ( )  &&  ! domainMissing  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 03:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													// No difference in terms of domainIPs and nothing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// has changed so we don't change anything on the etcd.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// Additionally also check if domain is updated/missing with more
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// entries, if that is the case we should update the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// new domain entries as well.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 03:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 03:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// if domain IPs intersect then it won't be an empty set.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// such an intersection means that bucket exists on etcd.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// but if we do see a difference with local domain IPs with
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// hostSlice from etcd then we should update with newer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// domainIPs, we proceed to do that here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bucketsToBeUpdated . Add ( bucket . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 03:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// No IPs seem to intersect, this means that bucket exists but has
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// different IP addresses perhaps from a different deployment.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// bucket names are globally unique in federation at a given
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// path prefix, name collision is not allowed. We simply log
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// an error and continue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketsInConflict . Add ( bucket . Name ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 23:49:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Add/update buckets that are not registered with the DNS
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucketsToBeUpdatedSlice  :=  bucketsToBeUpdated . ToSlice ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-10 04:08:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									g  :=  errgroup . WithNErrs ( len ( bucketsToBeUpdatedSlice ) ) . WithConcurrency ( 50 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  index  :=  range  bucketsToBeUpdatedSlice  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-15 00:44:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										index  :=  index 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-05 23:18:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										g . Go ( func ( )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  globalDNSConfig . Put ( bucketsToBeUpdatedSlice [ index ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-05 23:18:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ,  index ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-16 01:46:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  GlobalContext 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  err  :=  range  g . Wait ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 23:49:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  bucket  :=  range  bucketsInConflict . ToSlice ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-10 04:08:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to add bucket DNS entry for bucket %s, an entry exists for the same bucket by a different tenant. This local bucket will be ignored. Bucket names are globally unique in federated deployments. Use path style requests on following addresses '%v' to access this bucket" ,  bucket ,  globalDomainIPs . ToSlice ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  wg  sync . WaitGroup 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 23:49:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Remove buckets that are in DNS for this server, but aren't local
 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  bucket ,  records  :=  range  dnsBuckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  bucketsSet . Contains ( bucket )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 23:49:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  globalDomainIPs . Intersection ( set . CreateStringSet ( getHostsSlice ( records ) ... ) ) . IsEmpty ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 23:49:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// This is not for our server, so we can continue
 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 23:49:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										wg . Add ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										go  func ( bucket  string )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defer  wg . Done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// We go to here, so we know the bucket no longer exists,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// but is registered in DNS to this server
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  globalDNSConfig . Delete ( bucket ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												logger . LogIf ( GlobalContext ,  fmt . Errorf ( "Failed to remove DNS entry for %s due to %w" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bucket ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ( bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-05 23:18:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									wg . Wait ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-05 23:18:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-12-27 15:38:38 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// GetBucketLocationHandler - GET Bucket location.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// -------------------------
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This operation returns bucket location.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  GetBucketLocationHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
									
										
										
										
											2018-07-21 09:46:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "GetBucketLocation" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-15 03:01:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-27 15:38:38 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  s3Error  :=  checkRequestAuthType ( ctx ,  r ,  policy . GetBucketLocationAction ,  bucket ,  "" ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-22 05:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-05 04:52:25 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-29 05:14:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									getBucketInfo  :=  objectAPI . GetBucketInfo 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  err  :=  getBucketInfo ( ctx ,  bucket ,  BucketOptions { } ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-20 09:49:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-27 15:38:38 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Generate response.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-07 04:16:22 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									encodedSuccessResponse  :=  encodeResponse ( LocationResponse { } ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												config/main: Re-write config files - add to new config v3
- New config format.
```
{
	"version": "3",
	"address": ":9000",
    "backend": {
          "type": "fs",
          "disk": "/path"
    },
	"credential": {
		"accessKey": "WLGDGYAQYIGI833EV05A",
		"secretKey": "BYvgJM101sHngl2uzjXS/OBF/aMxAN06JrJ3qJlF"
	},
	"region": "us-east-1",
	"logger": {
		"file": {
			"enable": false,
			"fileName": "",
			"level": "error"
		},
		"syslog": {
			"enable": false,
			"address": "",
			"level": "debug"
		},
		"console": {
			"enable": true,
			"level": "fatal"
		}
	}
}
```
New command lines in lieu of supporting XL.
Minio initialize filesystem backend.
~~~
$ minio init fs <path>
~~~
Minio initialize XL backend.
~~~
$ minio init xl <url1>...<url16>
~~~
For 'fs' backend it starts the server.
~~~
$ minio server
~~~
For 'xl' backend it waits for servers to join.
~~~
$ minio server
... [PROGRESS BAR] of servers connecting
~~~
Now on other servers execute 'join' and they connect.
~~~
....
minio join <url1> -- from <url2> && minio server
minio join <url1> -- from <url3> && minio server
...
...
minio join <url1> -- from <url16> && minio server
~~~
											 
										 
										
											2016-02-13 07:27:10 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Get current region.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 05:06:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									region  :=  globalSite . Region 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  region  !=  globalMinioDefaultRegion  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-07 04:16:22 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										encodedSuccessResponse  =  encodeResponse ( LocationResponse { 
							 
						 
					
						
							
								
									
										
											 
										
											
												config/main: Re-write config files - add to new config v3
- New config format.
```
{
	"version": "3",
	"address": ":9000",
    "backend": {
          "type": "fs",
          "disk": "/path"
    },
	"credential": {
		"accessKey": "WLGDGYAQYIGI833EV05A",
		"secretKey": "BYvgJM101sHngl2uzjXS/OBF/aMxAN06JrJ3qJlF"
	},
	"region": "us-east-1",
	"logger": {
		"file": {
			"enable": false,
			"fileName": "",
			"level": "error"
		},
		"syslog": {
			"enable": false,
			"address": "",
			"level": "debug"
		},
		"console": {
			"enable": true,
			"level": "fatal"
		}
	}
}
```
New command lines in lieu of supporting XL.
Minio initialize filesystem backend.
~~~
$ minio init fs <path>
~~~
Minio initialize XL backend.
~~~
$ minio init xl <url1>...<url16>
~~~
For 'fs' backend it starts the server.
~~~
$ minio server
~~~
For 'xl' backend it waits for servers to join.
~~~
$ minio server
... [PROGRESS BAR] of servers connecting
~~~
Now on other servers execute 'join' and they connect.
~~~
....
minio join <url1> -- from <url2> && minio server
minio join <url1> -- from <url3> && minio server
...
...
minio join <url1> -- from <url16> && minio server
~~~
											 
										 
										
											2016-02-13 07:27:10 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											Location :  region , 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 16:37:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Write success response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									writeSuccessResponseXML ( w ,  encodedSuccessResponse ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-27 15:38:38 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 11:15:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// ListMultipartUploadsHandler - GET Bucket (List Multipart uploads)
  
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// -------------------------
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This operation lists in-progress multipart uploads. An in-progress
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// multipart upload is a multipart upload that has been initiated,
  
						 
					
						
							
								
									
										
										
										
											2015-10-17 10:09:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// using the Initiate Multipart Upload request, but has not yet been
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// completed or aborted. This operation returns at most 1,000 multipart
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// uploads in the response.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  ListMultipartUploadsHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
									
										
										
										
											2018-07-21 09:46:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "ListMultipartUploads" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-15 03:01:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-17 10:09:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  s3Error  :=  checkRequestAuthType ( ctx ,  r ,  policy . ListBucketMultipartUploadsAction ,  bucket ,  "" ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-05 04:52:25 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-08 13:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									prefix ,  keyMarker ,  uploadIDMarker ,  delimiter ,  maxUploads ,  encodingType ,  errCode  :=  getBucketMultipartResources ( r . Form ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  errCode  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( errCode ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 22:31:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												objectAPI: Fix object API interface, remove unnecessary structs.
ObjectAPI changes.
```
ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, *probe.Error)
ListMultipartUploads(bucket, objectPrefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int) (ListMultipartsInfo, *probe.Error)
ListObjectParts(bucket, object, uploadID string, partNumberMarker, maxParts int) (ListPartsInfo, *probe.Error)
CompleteMultipartUpload(bucket string, object string, uploadID string, parts []completePart) (ObjectInfo, *probe.Error)
```
											 
										 
										
											2016-04-03 16:34:20 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  maxUploads  <  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrInvalidMaxUploads ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-17 08:22:45 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-04-06 03:26:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  keyMarker  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-30 05:24:10 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// Marker not common with prefix is not implemented.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-06 15:16:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! HasPrefix ( keyMarker ,  prefix )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrNotImplemented ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-30 05:24:10 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-06 03:26:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-15 03:01:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									listMultipartsInfo ,  err  :=  objectAPI . ListMultipartUploads ( ctx ,  bucket ,  prefix ,  keyMarker ,  uploadIDMarker ,  delimiter ,  maxUploads ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-19 18:20:07 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-04 07:17:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-19 18:20:07 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// generate response
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-24 14:14:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									response  :=  generateListMultipartUploadsResponse ( bucket ,  listMultipartsInfo ,  encodingType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-07 04:16:22 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									encodedSuccessResponse  :=  encodeResponse ( response ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 16:37:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-08 16:40:06 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// write success response.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 16:37:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									writeSuccessResponseXML ( w ,  encodedSuccessResponse ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 00:21:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ListBucketsHandler - GET Service.
  
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// -----------
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This implementation of the GET operation returns a list of all buckets
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// owned by the authenticated sender of the request.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  ListBucketsHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
									
										
										
										
											2018-07-21 09:46:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "ListBuckets" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-15 03:01:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									listBuckets  :=  objectAPI . ListBuckets 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-03 03:29:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cred ,  owner ,  s3Error  :=  checkRequestAuthTypeCredential ( ctx ,  r ,  policy . ListAllMyBucketsAction ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 03:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  s3Error  !=  ErrNone  &&  s3Error  !=  ErrAccessDenied  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-05 04:52:25 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 12:37:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Anonymous users, should be rejected.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  cred . AccessKey  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrAccessDenied ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 12:37:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// If etcd, dns federation configured list buckets from etcd.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  bucketsInfo  [ ] BucketInfo 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-30 00:56:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalDNSConfig  !=  nil  &&  globalBucketFederation  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dnsBuckets ,  err  :=  globalDNSConfig . List ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  &&  ! IsErrIgnored ( err , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dns . ErrNoEntriesFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dns . ErrDomainMissing )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  dnsRecords  :=  range  dnsBuckets  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketsInfo  =  append ( bucketsInfo ,  BucketInfo { 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Name :     dnsRecords [ 0 ] . Key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Created :  dnsRecords [ 0 ] . CreationDate , 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 03:44:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sort . Slice ( bucketsInfo ,  func ( i ,  j  int )  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  bucketsInfo [ i ] . Name  <  bucketsInfo [ j ] . Name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Invoke the list buckets.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bucketsInfo ,  err  =  listBuckets ( ctx ,  BucketOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-04 07:17:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 04:23:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 03:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  s3Error  ==  ErrAccessDenied  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Set prefix value for "s3:prefix" policy conditionals.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . Header . Set ( "prefix" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Set delimiter value for "s3:delimiter" policy conditionals.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . Header . Set ( "delimiter" ,  SlashSeparator ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Use the following trick to filter in place
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// https://github.com/golang/go/wiki/SliceTricks#filter-in-place
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  bucketInfo  :=  range  bucketsInfo  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-24 06:15:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												AccountName :      cred . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Groups :           cred . Groups , 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 03:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Action :           iampolicy . ListBucketAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :       bucketInfo . Name , 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-13 09:07:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  cred . AccessKey ,  cred . Claims ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 03:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       "" , 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-13 09:07:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Claims :           cred . Claims , 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 03:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bucketsInfo [ n ]  =  bucketInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												n ++ 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 01:46:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												AccountName :      cred . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Groups :           cred . Groups , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Action :           iampolicy . GetBucketLocationAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :       bucketInfo . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  cred . AccessKey ,  cred . Claims ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Claims :           cred . Claims , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bucketsInfo [ n ]  =  bucketInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												n ++ 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 03:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketsInfo  =  bucketsInfo [ : n ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// No buckets can be filtered return access denied error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( bucketsInfo )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 03:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-13 01:27:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 04:23:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Generate response.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 03:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									response  :=  generateListBucketsResponse ( bucketsInfo ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 04:23:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									encodedSuccessResponse  :=  encodeResponse ( response ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 16:37:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 04:23:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Write response.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 16:37:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									writeSuccessResponseXML ( w ,  encodedSuccessResponse ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// DeleteMultipleObjectsHandler - deletes multiple objects.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  DeleteMultipleObjectsHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
									
										
										
										
											2018-07-21 09:46:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "DeleteMultipleObjects" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-15 03:01:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-03 09:40:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-23 11:36:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Content-Md5 is requied should be set
 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html
 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-23 11:36:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  ok  :=  r . Header [ xhttp . ContentMD5 ] ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMissingContentMD5 ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-23 11:36:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Content-Length is required and should be non-zero
 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html
 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-23 11:36:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  r . ContentLength  <=  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMissingContentLength ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-21 13:59:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// The max. XML contains 100000 object names (each at most 1024 bytes long) + XML overhead
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  maxBodySize  =  2  *  100000  *  1024 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Unmarshal list of keys to be deleted.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									deleteObjectsReq  :=  & DeleteObjectsRequest { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  xmlDecoder ( r . Body ,  deleteObjectsReq ,  maxBodySize ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-12 09:50:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logger . LogIf ( ctx ,  err ,  logger . Application ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-28 07:44:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 17:28:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objects  :=  make ( [ ] ObjectV ,  len ( deleteObjectsReq . Objects ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 05:57:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Convert object name delete objects if it has `/` in the beginning.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i  :=  range  deleteObjectsReq . Objects  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										deleteObjectsReq . Objects [ i ] . ObjectName  =  trimLeadingSlash ( deleteObjectsReq . Objects [ i ] . ObjectName ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 17:28:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										objects [ i ]  =  deleteObjectsReq . Objects [ i ] . ObjectV 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 05:57:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 17:28:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Make sure to update context to print ObjectNames for multi objects.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  =  updateReqContext ( ctx ,  objects ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-05 01:13:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Call checkRequestAuthType to populate ReqInfo.AccessKey before GetBucketInfo()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Ignore errors here to preserve the S3 error behavior of GetBucketInfo()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									checkRequestAuthType ( ctx ,  r ,  policy . DeleteObjectAction ,  bucket ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-10 23:30:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Before proceeding validate if bucket exists.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  :=  objectAPI . GetBucketInfo ( ctx ,  bucket ,  BucketOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-10 23:30:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-10 23:30:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-14 03:25:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									deleteObjectsFn  :=  objectAPI . DeleteObjects 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-21 12:21:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  api . CacheAPI ( )  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-14 03:25:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										deleteObjectsFn  =  api . CacheAPI ( ) . DeleteObjects 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-21 12:21:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-02 16:59:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-18 23:38:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Return Malformed XML as S3 spec if the number of objects is empty
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( deleteObjectsReq . Objects )  ==  0  ||  len ( deleteObjectsReq . Objects )  >  maxDeleteList  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMalformedXML ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-14 01:48:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectsToDelete  :=  map [ ObjectToDelete ] int { } 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									getObjectInfoFn  :=  objectAPI . GetObjectInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  api . CacheAPI ( )  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										getObjectInfoFn  =  api . CacheAPI ( ) . GetObjectInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-17 22:50:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 03:24:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 04:31:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hasLockEnabled  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dsc             ReplicateDecision 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goi             ObjectInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										gerr            error 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 03:24:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									replicateDeletes  :=  hasReplicationRules ( ctx ,  bucket ,  deleteObjectsReq . Objects ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 03:24:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  rcfg ,  _  :=  globalBucketObjectLockSys . Get ( bucket ) ;  rcfg . LockEnabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hasLockEnabled  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-20 01:30:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									type  deleteResult  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delInfo  DeletedObject 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errInfo  DeleteError 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									deleteResults  :=  make ( [ ] deleteResult ,  len ( deleteObjectsReq . Objects ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-07 10:05:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									vc ,  _  :=  globalBucketVersioningSys . Get ( bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									oss  :=  make ( [ ] * objSweeper ,  len ( deleteObjectsReq . Objects ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  index ,  object  :=  range  deleteObjectsReq . Objects  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  apiErrCode  :=  checkRequestAuthType ( ctx ,  r ,  policy . DeleteObjectAction ,  bucket ,  object . ObjectName ) ;  apiErrCode  !=  ErrNone  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  apiErrCode  ==  ErrSignatureDoesNotMatch  ||  apiErrCode  ==  ErrInvalidAccessKeyID  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( apiErrCode ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-22 22:54:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-16 03:49:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											apiErr  :=  errorCodes . ToAPIErr ( apiErrCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											deleteResults [ index ] . errInfo  =  DeleteError { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Code :       apiErr . Code , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Message :    apiErr . Description , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Key :        object . ObjectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												VersionID :  object . VersionID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-21 12:21:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-12 12:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  object . VersionID  !=  ""  &&  object . VersionID  !=  nullVersionID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  err  :=  uuid . Parse ( object . VersionID ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "invalid version-id specified %w" ,  err ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												apiErr  :=  errorCodes . ToAPIErr ( ErrNoSuchVersion ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												deleteResults [ index ] . errInfo  =  DeleteError { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-12 12:44:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Code :       apiErr . Code , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Message :    apiErr . Description , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Key :        object . ObjectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													VersionID :  object . VersionID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-17 22:50:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										opts  :=  ObjectOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											VersionID :         object . VersionID , 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-07 10:05:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Versioned :         vc . PrefixEnabled ( object . ObjectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 13:06:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											VersionSuspended :  vc . Suspended ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-17 22:50:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-01 03:57:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  replicateDeletes  ||  object . VersionID  !=  ""  &&  hasLockEnabled  ||  ! globalTierConfigMgr . Empty ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-17 22:50:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! globalTierConfigMgr . Empty ( )  &&  object . VersionID  ==  ""  &&  opts . VersionSuspended  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												opts . VersionID  =  nullVersionID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goi ,  gerr  =  getObjectInfoFn ( ctx ,  bucket ,  object . ObjectName ,  opts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! globalTierConfigMgr . Empty ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-07 10:05:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											oss [ index ]  =  newObjSweeper ( bucket ,  object . ObjectName ) . WithVersion ( opts . VersionID ) . WithVersioning ( opts . Versioned ,  opts . VersionSuspended ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-17 22:50:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											oss [ index ] . SetTransitionState ( goi . TransitionedObject ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 03:24:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-17 22:50:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 03:24:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  replicateDeletes  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 04:31:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											dsc  =  checkReplicateDelete ( ctx ,  bucket ,  ObjectToDelete { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 17:28:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ObjectV :  ObjectV { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ObjectName :  object . ObjectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													VersionID :   object . VersionID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 04:31:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ,  goi ,  opts ,  gerr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  dsc . ReplicateAny ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 03:24:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  object . VersionID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													object . VersionPurgeStatus  =  Pending 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 04:31:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													object . VersionPurgeStatuses  =  dsc . PendingStatus ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 03:24:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 04:31:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													object . DeleteMarkerReplicationStatus  =  dsc . PendingStatus ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 03:24:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 04:31:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												object . ReplicateDecisionStr  =  dsc . String ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-26 03:24:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-01 03:57:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  object . VersionID  !=  ""  &&  hasLockEnabled  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-17 22:50:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  apiErrCode  :=  enforceRetentionBypassForDelete ( ctx ,  r ,  bucket ,  object ,  goi ,  gerr ) ;  apiErrCode  !=  ErrNone  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												apiErr  :=  errorCodes . ToAPIErr ( apiErrCode ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												deleteResults [ index ] . errInfo  =  DeleteError { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-17 22:50:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Code :       apiErr . Code , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Message :    apiErr . Description , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Key :        object . ObjectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													VersionID :  object . VersionID , 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-17 22:50:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-20 09:42:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Avoid duplicate objects, we use map to filter them out.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  _ ,  ok  :=  objectsToDelete [ object ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectsToDelete [ object ]  =  index 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-20 09:42:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-14 03:25:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									toNames  :=  func ( input  map [ ObjectToDelete ] int )  ( output  [ ] ObjectToDelete )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										output  =  make ( [ ] ObjectToDelete ,  len ( input ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 09:51:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										idx  :=  0 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  obj  :=  range  input  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											output [ idx ]  =  obj 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 09:51:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											idx ++ 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-22 22:54:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-14 03:25:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-07 02:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Disable timeouts and cancellation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  =  bgContext ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 09:51:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									deleteList  :=  toNames ( objectsToDelete ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dObjects ,  errs  :=  deleteObjectsFn ( ctx ,  bucket ,  deleteList ,  ObjectOptions { 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 13:06:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										PrefixEnabledFn :   vc . PrefixEnabled , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										VersionSuspended :  vc . Suspended ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i  :=  range  errs  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 08:15:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// DeleteMarkerVersionID is not used specifically to avoid
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// lookup errors, since DeleteMarkerVersionID is only
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// created during DeleteMarker creation when client didn't
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// specify a versionID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objToDel  :=  ObjectToDelete { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 17:28:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ObjectV :  ObjectV { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :  dObjects [ i ] . ObjectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												VersionID :   dObjects [ i ] . VersionID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 04:31:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											VersionPurgeStatus :             dObjects [ i ] . VersionPurgeStatus ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											VersionPurgeStatuses :           dObjects [ i ] . ReplicationState . VersionPurgeStatusInternal , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											DeleteMarkerReplicationStatus :  dObjects [ i ] . ReplicationState . ReplicationStatusInternal , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ReplicateDecisionStr :           dObjects [ i ] . ReplicationState . ReplicateDecisionStr , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 08:15:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dindex  :=  objectsToDelete [ objToDel ] 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-12 04:39:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  errs [ i ]  ==  nil  ||  isErrObjectNotFound ( errs [ i ] )  ||  isErrVersionNotFound ( errs [ i ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-13 04:10:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  replicateDeletes  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-19 04:31:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dObjects [ i ] . ReplicationState  =  deleteList [ i ] . ReplicationState ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-13 04:10:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											deleteResults [ dindex ] . delInfo  =  dObjects [ i ] 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-13 04:10:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiErr  :=  toAPIError ( ctx ,  errs [ i ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										deleteResults [ dindex ] . errInfo  =  DeleteError { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Code :       apiErr . Code , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Message :    apiErr . Description , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Key :        deleteList [ i ] . ObjectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											VersionID :  deleteList [ i ] . VersionID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-02 16:59:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Generate response
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									deleteErrors  :=  make ( [ ] DeleteError ,  0 ,  len ( deleteObjectsReq . Objects ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									deletedObjects  :=  make ( [ ] DeletedObject ,  0 ,  len ( deleteObjectsReq . Objects ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  deleteResult  :=  range  deleteResults  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  deleteResult . errInfo . Code  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											deleteErrors  =  append ( deleteErrors ,  deleteResult . errInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											deletedObjects  =  append ( deletedObjects ,  deleteResult . delInfo ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-08 02:49:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-02 16:59:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 02:01:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									response  :=  generateMultiDeleteResponse ( deleteObjectsReq . Quiet ,  deletedObjects ,  deleteErrors ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									encodedSuccessResponse  :=  encodeResponse ( response ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 16:37:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Write success response.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 16:37:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									writeSuccessResponseXML ( w ,  encodedSuccessResponse ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 10:43:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  dobj  :=  range  deletedObjects  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-11 14:00:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  dobj . ObjectName  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 13:06:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  replicateDeletes  &&  ( dobj . DeleteMarkerReplicationStatus ( )  ==  replication . Pending  ||  dobj . VersionPurgeStatus ( )  ==  Pending )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dv  :=  DeletedObjectReplicationInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												DeletedObject :  dobj , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Bucket :         bucket , 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-13 01:43:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												EventType :      ReplicateIncomingDelete , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-13 04:10:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 13:06:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											scheduleReplicationDelete ( ctx ,  dv ,  objectAPI ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-17 22:50:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-17 12:22:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										eventName  :=  event . ObjectRemovedDelete 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										objInfo  :=  ObjectInfo { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 08:15:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Name :          dobj . ObjectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											VersionID :     dobj . VersionID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											DeleteMarker :  dobj . DeleteMarker , 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-17 12:22:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-31 08:15:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  objInfo . DeleteMarker  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-17 12:22:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objInfo . VersionID  =  dobj . DeleteMarkerVersionID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											eventName  =  event . ObjectRemovedDeleteMarkerCreated 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-17 12:22:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sendEvent ( eventArgs { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-17 12:22:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											EventName :     eventName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											BucketName :    bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Object :        objInfo , 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-03 09:40:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ReqParams :     extractReqParams ( r ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											RespElements :  extractRespElements ( w ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											UserAgent :     r . UserAgent ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 02:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Host :          handlers . GetSourceIP ( r ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-29 13:46:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-02 16:59:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-13 09:57:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Clean up transitioned objects from remote tier
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  os  :=  range  oss  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  os  ==  nil  {  // skip objects that weren't deleted due to invalid versionID etc.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										logger . LogIf ( ctx ,  os . Sweep ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-06 08:43:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 11:15:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// PutBucketHandler - PUT Bucket
  
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// ----------
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This implementation of the PUT operation creates a new bucket for authenticated request
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  PutBucketHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
									
										
										
										
											2018-07-21 09:46:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "PutBucket" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-15 03:01:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectLockEnabled  :=  false 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:44:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  vs  :=  r . Header . Get ( xhttp . AmzObjectLockEnabled ) ;  len ( vs )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										v  :=  strings . ToLower ( vs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  v  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "true" ,  "false" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectLockEnabled  =  v  ==  "true" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrInvalidRequest ) ,  r . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									forceCreate  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  vs  :=  r . Header . Get ( xhttp . MinIOForceCreate ) ;  len ( vs )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										v  :=  strings . ToLower ( vs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  v  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "true" ,  "false" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											forceCreate  =  v  ==  "true" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrInvalidRequest ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-03 03:29:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cred ,  owner ,  s3Error  :=  checkRequestAuthTypeCredential ( ctx ,  r ,  policy . CreateBucketAction ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-06 07:27:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-05 04:52:25 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-15 00:17:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-06 07:27:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  objectLockEnabled  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Creating a bucket with locking requires the user having more permissions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  action  :=  range  [ ] iampolicy . Action { iampolicy . PutBucketObjectLockConfigurationAction ,  iampolicy . PutBucketVersioningAction }  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												AccountName :      cred . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Groups :           cred . Groups , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Action :           action , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  cred . AccessKey ,  cred . Claims ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :       bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Claims :           cred . Claims , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrAccessDenied ) ,  r . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-04 05:50:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Parse incoming location constraint.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									location ,  s3Error  :=  parseLocationConstraint ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-26 11:00:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-21 08:35:38 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-24 13:51:12 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-04 05:50:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Validate if location sent by the client is valid, reject
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// requests which do not follow valid region requirements.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! isValidLocation ( location )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrInvalidRegion ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-04 05:50:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-09 18:06:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// check if client is attempting to create more buckets than allowed maximum.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  currBuckets  :=  globalBucketMetadataSys . Count ( ) ;  currBuckets + 1  >  maxBuckets  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiErr  :=  errorCodes . ToAPIErr ( ErrTooManyBuckets ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiErr . Description  =  fmt . Sprintf ( "You have attempted to create %d buckets than allowed %d" ,  currBuckets + 1 ,  maxBuckets ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  apiErr ,  r . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									opts  :=  MakeBucketOptions { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Location :     location , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										LockEnabled :  objectLockEnabled , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:44:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ForceCreate :  forceCreate , 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalDNSConfig  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-23 00:25:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sr ,  err  :=  globalDNSConfig . Get ( bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 03:20:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// ErrNotImplemented indicates a DNS backend that doesn't need to check if bucket already
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// exists elsewhere
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  dns . ErrNoEntriesFound  ||  err  ==  dns . ErrNotImplemented  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Proceed to creating a bucket.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  =  objectAPI . MakeBucketWithLocation ( ctx ,  bucket ,  opts ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-02 00:53:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  =  globalDNSConfig . Put ( bucket ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													objectAPI . DeleteBucket ( context . Background ( ) ,  bucket ,  DeleteBucketOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														Force :       false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														NoRecreate :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														SRDeleteOp :  getSRBucketDeleteOp ( globalSiteReplicationSys . isEnabled ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 02:03:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Load updated bucket metadata into memory.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												globalNotificationSys . LoadBucketMetadata ( GlobalContext ,  bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Make sure to add Location information here only for bucket
 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 13:34:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												w . Header ( ) . Set ( xhttp . Location , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													getObjectLocation ( r ,  globalDomainNames ,  bucket ,  "" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												writeSuccessResponseHeadersOnly ( w ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sendEvent ( eventArgs { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													EventName :     event . BucketCreated , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													BucketName :    bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ReqParams :     extractReqParams ( r ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													RespElements :  extractRespElements ( w ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													UserAgent :     r . UserAgent ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Host :          handlers . GetSourceIP ( r ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-03 10:18:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-23 00:25:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiErr  :=  ErrBucketAlreadyExists 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! globalDomainIPs . Intersection ( set . CreateStringSet ( getHostsSlice ( sr ) ... ) ) . IsEmpty ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											apiErr  =  ErrBucketAlreadyOwnedByYou 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// No IPs seem to intersect, this means that bucket exists but has
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// different IP addresses perhaps from a different deployment.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// bucket names are globally unique in federation at a given
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// path prefix, name collision is not allowed. Return appropriate error.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( apiErr ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 09:45:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-24 13:51:12 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Proceed to creating a bucket.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-21 01:48:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  objectAPI . MakeBucketWithLocation ( ctx ,  bucket ,  opts ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  ok  :=  err . ( BucketExists ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Though bucket exists locally, we send the site-replication
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// hook to ensure all sites have this bucket. If the hook
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// succeeds, the client will still receive a bucket exists
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// message.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											globalSiteReplicationSys . MakeBucketHook ( ctx ,  bucket ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-04 07:17:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 16:37:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 02:03:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Load updated bucket metadata into memory.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalNotificationSys . LoadBucketMetadata ( GlobalContext ,  bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Call site replication hook
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-26 14:32:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalSiteReplicationSys . MakeBucketHook ( ctx ,  bucket ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-09-19 18:20:07 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Make sure to add Location information here only for bucket
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-16 07:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  cp  :=  pathClean ( r . URL . Path ) ;  cp  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . Header ( ) . Set ( xhttp . Location ,  cp )  // Clean any trailing slashes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 16:37:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									writeSuccessResponseHeadersOnly ( w ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sendEvent ( eventArgs { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										EventName :     event . BucketCreated , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :    bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ReqParams :     extractReqParams ( r ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RespElements :  extractRespElements ( w ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UserAgent :     r . UserAgent ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Host :          handlers . GetSourceIP ( r ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// PostPolicyBucketHandler - POST policy
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ----------
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This implementation of the POST operation handles object creation with a specified
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// signature policy in multipart/form-data
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  PostPolicyBucketHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
									
										
										
										
											2018-07-21 09:46:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "PostPolicyBucket" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-15 03:01:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 13:39:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  crypto . S3KMS . IsRequested ( r . Header )  {  // SSE-KMS is not supported
 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrNotImplemented ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 13:39:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-16 04:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-13 22:52:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  crypto . Requested ( r . Header )  &&  ! objectAPI . IsEncryptionSupported ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrNotImplemented ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 13:39:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 08:30:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bucket  :=  mux . Vars ( r ) [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Require Content-Length to be set in the request
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size  :=  r . ContentLength 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  size  <  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMissingContentLength ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 00:47:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-23 11:18:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									resource ,  err  :=  getResource ( r . URL . Path ,  r . Host ,  globalDomainNames ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-16 06:10:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrInvalidRequest ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-16 06:10:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 00:47:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Make sure that the URL does not contain object name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  bucket  !=  path . Clean ( resource [ 1 : ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMethodNotAllowed ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-16 06:10:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Here the parameter is the size of the form data that should
 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-23 08:54:31 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// be loaded in memory, the remaining being put in temporary files.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-30 05:24:10 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									reader ,  err  :=  r . MultipartReader ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMalformedPOSTRequest ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Read multipart data and save in memory and in the disk if needed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									form ,  err  :=  reader . ReadForm ( maxFormMemory ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-12 09:50:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logger . LogIf ( ctx ,  err ,  logger . Application ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMalformedPOSTRequest ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-10 13:18:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Remove all tmp files created during multipart upload
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  form . RemoveAll ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Extract all form fields
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									fileBody ,  fileName ,  fileSize ,  formValues ,  err  :=  extractPostPolicyFormValues ( ctx ,  form ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-05 04:52:25 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-12 09:50:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logger . LogIf ( ctx ,  err ,  logger . Application ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMalformedPOSTRequest ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-10 04:37:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if file is provided, error out otherwise.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  fileBody  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrPOSTFileRequired ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-10 04:37:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Close multipart file
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  fileBody . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									formValues . Set ( "Bucket" ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  fileName  !=  ""  &&  strings . Contains ( formValues . Get ( "Key" ) ,  "${filename}" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-28 08:51:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// S3 feature to replace ${filename} found in Key form field
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// by the filename attribute passed in multipart
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										formValues . Set ( "Key" ,  strings . ReplaceAll ( formValues . Get ( "Key" ) ,  "${filename}" ,  fileName ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 05:57:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									object  :=  trimLeadingSlash ( formValues . Get ( "Key" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-10 04:58:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									successRedirect  :=  formValues . Get ( "success_action_redirect" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									successStatus  :=  formValues . Get ( "success_action_status" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  redirectURL  * url . URL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  successRedirect  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										redirectURL ,  err  =  url . Parse ( successRedirect ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMalformedPOSTRequest ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-28 08:51:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Verify policy signature.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 00:47:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cred ,  errCode  :=  doesPolicySignatureMatch ( formValues ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  errCode  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( errCode ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-25 14:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 00:47:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Once signature is validated, check if the user has
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// explicit permissions for the user.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-13 09:07:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AccountName :      cred . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-27 13:53:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Groups :           cred . Groups , 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-13 09:07:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Action :           iampolicy . PutObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConditionValues :  getConditionValues ( r ,  "" ,  cred . AccessKey ,  cred . Claims ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :       bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ObjectName :       object , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										IsOwner :          globalActiveCred . AccessKey  ==  cred . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Claims :           cred . Claims , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrAccessDenied ) ,  r . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-04 00:47:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									policyBytes ,  err  :=  base64 . StdEncoding . DecodeString ( formValues . Get ( "Policy" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-25 14:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMalformedPOSTRequest ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-25 14:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 04:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Handle policy if it is set.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( policyBytes )  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-26 04:57:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										postPolicyForm ,  err  :=  parsePostPolicyForm ( bytes . NewReader ( policyBytes ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 04:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-26 04:57:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											errAPI  :=  errorCodes . ToAPIErr ( ErrPostPolicyConditionInvalidFormat ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											errAPI . Description  =  fmt . Sprintf ( "%s '(%s)'" ,  errAPI . Description ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  errAPI ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 20:15:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 04:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Make sure formValues adhere to policy restrictions.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-06 04:10:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  =  checkPostPolicy ( formValues ,  postPolicyForm ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErrWithErr ( ErrAccessDenied ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 20:15:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 04:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Ensure that the object size is within expected range, also the file size
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// should not exceed the maximum single Put size (5 GiB)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lengthRange  :=  postPolicyForm . Conditions . ContentLengthRange 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  lengthRange . Valid  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  fileSize  <  lengthRange . Min  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  errDataTooSmall ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 04:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  fileSize  >  lengthRange . Max  ||  isMaxObjectSize ( fileSize )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  errDataTooLarge ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-04 04:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-25 14:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-20 08:14:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Extract metadata to be saved from received Form.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-11 11:27:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									metadata  :=  make ( map [ string ] string ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-04 12:41:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  extractMetadataFromMime ( ctx ,  textproto . MIMEHeader ( formValues ) ,  metadata ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-06 07:56:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-06 07:56:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 06:51:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												pkg/etag: add new package for S3 ETag handling (#11577)
This commit adds a new package `etag` for dealing
with S3 ETags.
Even though ETag is often viewed as MD5 checksum of
an object, handling S3 ETags correctly is a surprisingly
complex task. While it is true that the ETag corresponds
to the MD5 for the most basic S3 API operations, there are
many exceptions in case of multipart uploads or encryption.
In worse, some S3 clients expect very specific behavior when
it comes to ETags. For example, some clients expect that the
ETag is a double-quoted string and fail otherwise.
Non-AWS compliant ETag handling has been a source of many bugs
in the past.
Therefore, this commit adds a dedicated `etag` package that provides
functionality for parsing, generating and converting S3 ETags.
Further, this commit removes the ETag computation from the `hash`
package. Instead, the `hash` package (i.e. `hash.Reader`) should
focus only on computing and verifying the content-sha256.
One core feature of this commit is to provide a mechanism to
communicate a computed ETag from a low-level `io.Reader` to
a high-level `io.Reader`.
This problem occurs when an S3 server receives a request and
has to compute the ETag of the content. However, the server
may also wrap the initial body with several other `io.Reader`,
e.g. when encrypting or compressing the content:
```
   reader := Encrypt(Compress(ETag(content)))
```
In such a case, the ETag should be accessible by the high-level
`io.Reader`.
The `etag` provides a mechanism to wrap `io.Reader` implementations
such that the `ETag` can be accessed by a type-check.
This technique is applied to the PUT, COPY and Upload handlers.
											 
										 
										
											2021-02-24 04:31:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hashReader ,  err  :=  hash . NewReader ( fileBody ,  fileSize ,  "" ,  "" ,  fileSize ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-15 09:36:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rawReader  :=  hashReader 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-11 00:52:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pReader  :=  NewPutObjReader ( rawReader ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 08:01:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  objectEncryptionKey  crypto . ObjectKey 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-05 17:42:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket encryption is enabled
 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-14 15:59:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sseConfig ,  _  :=  globalBucketSSEConfigSys . Get ( bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 00:02:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sseConfig . Apply ( r . Header ,  sse . ApplyOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AutoEncrypt :  globalAutoEncryption , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-01-06 06:16:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  opts  ObjectOptions 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 13:31:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									opts ,  err  =  putOpts ( ctx ,  r ,  bucket ,  object ,  metadata ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-06 06:16:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponseHeadersOnly ( w ,  toAPIError ( ctx ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-06 06:16:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-06 00:02:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  objectAPI . IsEncryptionSupported ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-13 22:52:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  crypto . Requested ( formValues )  &&  ! HasSuffix ( object ,  SlashSeparator )  {  // handle SSE requests
 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-21 05:56:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  crypto . SSECopy . IsRequested ( r . Header )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  errInvalidEncryptionParameters ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-21 05:56:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 06:24:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reader  io . Reader 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												keyID   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												key     [ ] byte 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-11 09:15:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												kmsCtx  kms . Context 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 06:24:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											kind ,  _  :=  crypto . IsRequested ( formValues ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  kind  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  crypto . SSEC : 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												key ,  err  =  ParseSSECustomerHeader ( formValues ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 06:24:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  crypto . S3KMS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												keyID ,  kmsCtx ,  err  =  crypto . S3KMS . ParseHTTP ( formValues ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 06:24:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-06 00:02:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-19 09:54:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reader ,  objectEncryptionKey ,  err  =  newEncryptReader ( ctx ,  hashReader ,  kind ,  keyID ,  key ,  bucket ,  object ,  metadata ,  kmsCtx ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-06 00:02:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-06 00:02:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											info  :=  ObjectInfo { Size :  fileSize } 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-09 09:35:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// do not try to verify encrypted content
 
							 
						 
					
						
							
								
									
										
											 
										
											
												pkg/etag: add new package for S3 ETag handling (#11577)
This commit adds a new package `etag` for dealing
with S3 ETags.
Even though ETag is often viewed as MD5 checksum of
an object, handling S3 ETags correctly is a surprisingly
complex task. While it is true that the ETag corresponds
to the MD5 for the most basic S3 API operations, there are
many exceptions in case of multipart uploads or encryption.
In worse, some S3 clients expect very specific behavior when
it comes to ETags. For example, some clients expect that the
ETag is a double-quoted string and fail otherwise.
Non-AWS compliant ETag handling has been a source of many bugs
in the past.
Therefore, this commit adds a dedicated `etag` package that provides
functionality for parsing, generating and converting S3 ETags.
Further, this commit removes the ETag computation from the `hash`
package. Instead, the `hash` package (i.e. `hash.Reader`) should
focus only on computing and verifying the content-sha256.
One core feature of this commit is to provide a mechanism to
communicate a computed ETag from a low-level `io.Reader` to
a high-level `io.Reader`.
This problem occurs when an S3 server receives a request and
has to compute the ETag of the content. However, the server
may also wrap the initial body with several other `io.Reader`,
e.g. when encrypting or compressing the content:
```
   reader := Encrypt(Compress(ETag(content)))
```
In such a case, the ETag should be accessible by the high-level
`io.Reader`.
The `etag` provides a mechanism to wrap `io.Reader` implementations
such that the `ETag` can be accessed by a type-check.
This technique is applied to the PUT, COPY and Upload handlers.
											 
										 
										
											2021-02-24 04:31:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											hashReader ,  err  =  hash . NewReader ( reader ,  info . EncryptedSize ( ) ,  "" ,  "" ,  fileSize ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-06 00:02:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-06 00:02:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-11 00:52:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pReader ,  err  =  pReader . WithEncryption ( hashReader ,  & objectEncryptionKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-11 00:52:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-06 00:02:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 13:31:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objInfo ,  err  :=  objectAPI . PutObject ( ctx ,  bucket ,  object ,  pReader ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-05 04:52:25 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// We must not use the http.Header().Set method here because some (broken)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// clients expect the ETag header key to be literally "ETag" - not "Etag" (case-sensitive).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Therefore, we have to set the ETag directly as map entry.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 13:34:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . Header ( ) [ xhttp . ETag ]  =  [ ] string { ` " `  +  objInfo . ETag  +  ` " ` } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set the relevant version ID as part of the response header.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objInfo . VersionID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										w . Header ( ) [ xhttp . AmzVersionID ]  =  [ ] string { objInfo . VersionID } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . Header ( ) . Set ( xhttp . Location ,  getObjectLocation ( r ,  globalDomainNames ,  bucket ,  object ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-05 13:01:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Notify object created event.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  sendEvent ( eventArgs { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-03 09:40:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										EventName :     event . ObjectCreatedPost , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :    objInfo . Bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Object :        objInfo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ReqParams :     extractReqParams ( r ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RespElements :  extractRespElements ( w ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UserAgent :     r . UserAgent ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 02:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Host :          handlers . GetSourceIP ( r ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-13 22:46:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  redirectURL  !=  nil  {  // success_action_redirect is valid and set.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-16 06:04:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										v  :=  redirectURL . Query ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										v . Add ( "bucket" ,  objInfo . Bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										v . Add ( "key" ,  objInfo . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										v . Add ( "etag" ,  "\"" + objInfo . ETag + "\"" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										redirectURL . RawQuery  =  v . Encode ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeRedirectSeeOther ( w ,  redirectURL . String ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-24 13:51:12 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Decide what http response to send depending on success_action_status parameter
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  successStatus  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  "201" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  :=  encodeResponse ( PostResponse { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Bucket :    objInfo . Bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Key :       objInfo . Name , 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-15 03:05:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ETag :      ` " `  +  objInfo . ETag  +  ` " ` , 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Location :  w . Header ( ) . Get ( xhttp . Location ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeResponse ( w ,  http . StatusCreated ,  resp ,  mimeXML ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  "200" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeSuccessResponseHeadersOnly ( w ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-19 05:39:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeSuccessNoContent ( w ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-02 14:51:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 15:10:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// GetBucketPolicyStatusHandler -  Retrieves the policy status
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// for an MinIO bucket, indicating whether the bucket is public.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  GetBucketPolicyStatusHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "GetBucketPolicyStatus" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeErrorResponseHeadersOnly ( w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s3Error  :=  checkRequestAuthType ( ctx ,  r ,  policy . GetBucketPolicyStatusAction ,  bucket ,  "" ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeErrorResponseHeadersOnly ( w ,  errorCodes . ToAPIErr ( s3Error ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Check if bucket exists.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  err  :=  objectAPI . GetBucketInfo ( ctx ,  bucket ,  BucketOptions { } ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-02 15:10:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Check if anonymous (non-owner) has access to list objects.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									readable  :=  globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Action :           policy . ListBucketAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :       bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Check if anonymous (non-owner) has access to upload objects.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									writable  :=  globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Action :           policy . PutObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :       bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									encodedSuccessResponse  :=  encodeResponse ( PolicyStatus { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										IsPublic :  func ( )  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Silly to have special 'boolean' values yes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// but complying with silly implementation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketPolicyStatus.html
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  readable  &&  writable  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  "TRUE" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  "FALSE" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									writeSuccessResponseXML ( w ,  encodedSuccessResponse ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 11:15:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// HeadBucketHandler - HEAD Bucket
  
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// ----------
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This operation is useful to determine if a bucket exists.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The operation returns a 200 OK if the bucket exists and you
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// have permission to access it. Otherwise, the operation might
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return responses such as 404 Not Found and 403 Forbidden.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  HeadBucketHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
									
										
										
										
											2018-07-21 09:46:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "HeadBucket" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-15 03:01:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-16 09:42:39 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-03 11:31:22 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponseHeadersOnly ( w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-22 05:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  s3Error  :=  checkRequestAuthType ( ctx ,  r ,  policy . ListBucketAction ,  bucket ,  "" ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponseHeadersOnly ( w ,  errorCodes . ToAPIErr ( s3Error ) ) 
							 
						 
					
						
							
								
									
										
										
											
												accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
   "*":                             true,
   "s3:*":                          true,
   "s3:GetObject":                  true,
   "s3:ListBucket":                 true,
   "s3:PutObject":                  true,
   "s3:CreateBucket":               true,
   "s3:GetBucketLocation":          true,
   "s3:DeleteBucket":               true,
   "s3:DeleteObject":               true,
   "s3:AbortMultipartUpload":       true,
   "s3:ListBucketMultipartUploads": true,
   "s3:ListMultipartUploadParts":   true,
following conditions for "StringEquals" and "StringNotEquals"
   "s3:prefix", "s3:max-keys"
											 
										 
										
											2016-02-04 08:46:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-05 04:52:25 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-29 05:14:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									getBucketInfo  :=  objectAPI . GetBucketInfo 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  err  :=  getBucketInfo ( ctx ,  bucket ,  BucketOptions { } ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponseHeadersOnly ( w ,  toAPIError ( ctx ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-04 07:17:21 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 16:37:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-06 18:59:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									writeResponse ( w ,  http . StatusOK ,  nil ,  mimeXML ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-07-01 05:42:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2015-10-17 02:26:01 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// DeleteBucketHandler - Delete bucket
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  DeleteBucketHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
									
										
										
										
											2018-07-21 09:46:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "DeleteBucket" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-15 03:01:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 08:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 08:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-09 08:36:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Verify if the caller has sufficient permissions.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s3Error  :=  checkRequestAuthType ( ctx ,  r ,  policy . DeleteBucketAction ,  bucket ,  "" ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-09 08:36:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 12:52:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									forceDelete  :=  false 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 08:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  value  :=  r . Header . Get ( xhttp . MinIOForceDelete ) ;  value  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-09 08:36:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										forceDelete ,  err  =  strconv . ParseBool ( value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											apiErr  :=  errorCodes . ToAPIErr ( ErrInvalidRequest ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											apiErr . Description  =  err . Error ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  apiErr ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 12:52:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-09 08:36:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// if force delete header is set, we need to evaluate the policy anyways
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// regardless of it being true or not.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 08:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  s3Error  :=  checkRequestAuthType ( ctx ,  r ,  policy . ForceDeleteBucketAction ,  bucket ,  "" ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 08:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-11 09:47:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-09 08:36:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  forceDelete  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  rcfg ,  _  :=  globalBucketObjectLockSys . Get ( bucket ) ;  rcfg . LockEnabled  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMethodNotAllowed ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-09 08:36:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-09 06:28:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rcfg ,  err  :=  getReplicationConfig ( ctx ,  bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  err  !=  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  _ ,  ok  :=  err . ( BucketReplicationConfigNotFound ) ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMethodNotAllowed ) ,  r . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  rcfg . HasActiveRules ( "" ,  true ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrMethodNotAllowed ) ,  r . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-05 04:52:25 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 03:40:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalDNSConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  globalDNSConfig . Delete ( bucket ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to delete bucket DNS entry %w, please delete it manually" ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 03:40:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-29 05:14:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									deleteBucket  :=  objectAPI . DeleteBucket 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-24 13:51:12 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Attempt to delete bucket.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  deleteBucket ( ctx ,  bucket ,  DeleteBucketOptions { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Force :       forceDelete , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SRDeleteOp :  getSRBucketDeleteOp ( globalSiteReplicationSys . isEnabled ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 03:40:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiErr  :=  toAPIError ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  ok  :=  err . ( BucketNotEmpty ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  globalBucketVersioningSys . Enabled ( bucket )  ||  globalBucketVersioningSys . Suspended ( bucket )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												apiErr . Description  =  "The bucket you tried to delete is not empty. You must delete all versions in the bucket." 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 03:40:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  globalDNSConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err2  :=  globalDNSConfig . Put ( bucket ) ;  err2  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-15 06:09:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  fmt . Errorf ( "Unable to restore bucket DNS entry %w, please fix it manually" ,  err2 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-15 03:40:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  apiErr ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-17 02:26:01 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
											
												accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
   "*":                             true,
   "s3:*":                          true,
   "s3:GetObject":                  true,
   "s3:ListBucket":                 true,
   "s3:PutObject":                  true,
   "s3:CreateBucket":               true,
   "s3:GetBucketLocation":          true,
   "s3:DeleteBucket":               true,
   "s3:DeleteObject":               true,
   "s3:AbortMultipartUpload":       true,
   "s3:ListBucketMultipartUploads": true,
   "s3:ListMultipartUploadParts":   true,
following conditions for "StringEquals" and "StringNotEquals"
   "s3:prefix", "s3:max-keys"
											 
										 
										
											2016-02-04 08:46:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalNotificationSys . DeleteBucketMetadata ( ctx ,  bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 02:16:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalReplicationPool . deleteResyncMetadata ( ctx ,  bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Call site replication hook.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  globalSiteReplicationSys . DeleteBucketHook ( ctx ,  bucket ,  forceDelete ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
   "*":                             true,
   "s3:*":                          true,
   "s3:GetObject":                  true,
   "s3:ListBucket":                 true,
   "s3:PutObject":                  true,
   "s3:CreateBucket":               true,
   "s3:GetBucketLocation":          true,
   "s3:DeleteBucket":               true,
   "s3:DeleteObject":               true,
   "s3:AbortMultipartUpload":       true,
   "s3:ListBucketMultipartUploads": true,
   "s3:ListMultipartUploadParts":   true,
following conditions for "StringEquals" and "StringNotEquals"
   "s3:prefix", "s3:max-keys"
											 
										 
										
											2016-02-04 08:46:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Write success response.
 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-17 11:02:37 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									writeSuccessNoContent ( w ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sendEvent ( eventArgs { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										EventName :     event . BucketRemoved , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :    bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ReqParams :     extractReqParams ( r ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RespElements :  extractRespElements ( w ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UserAgent :     r . UserAgent ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Host :          handlers . GetSourceIP ( r ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-10-17 02:26:01 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PutBucketObjectLockConfigHandler - PUT Bucket object lock configuration.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ----------
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Places an Object Lock configuration on the specified bucket. The rule
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// specified in the Object Lock configuration will be applied by default
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// to every new object placed in the specified bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  PutBucketObjectLockConfigHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "PutBucketObjectLockConfig" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  s3Error  :=  checkRequestAuthType ( ctx ,  r ,  policy . PutBucketObjectLockConfigurationAction ,  bucket ,  "" ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 04:44:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									config ,  err  :=  objectlock . ParseObjectLockConfig ( r . Body ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 00:21:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiErr  :=  errorCodes . ToAPIErr ( ErrMalformedXML ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiErr . Description  =  err . Error ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  apiErr ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-02 00:53:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									configData ,  err  :=  xml . Marshal ( config ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-02 00:53:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 01:01:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Deny object locking configuration settings on existing buckets without object lock enabled.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  _ ,  err  =  globalBucketMetadataSys . GetObjectLockConfig ( bucket ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-24 01:01:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									updatedAt ,  err  :=  globalBucketMetadataSys . Update ( ctx ,  bucket ,  objectLockConfig ,  configData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Call site replication hook.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// We encode the xml bytes as base64 to ensure there are no encoding
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// errors.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfgStr  :=  base64 . StdEncoding . EncodeToString ( configData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  globalSiteReplicationSys . BucketMetaHook ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Type :              madmin . SRBucketMetaTypeObjectLockConfig , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Bucket :            bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ObjectLockConfig :  & cfgStr , 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										UpdatedAt :         updatedAt , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Write success response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									writeSuccessResponseHeadersOnly ( w ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetBucketObjectLockConfigHandler - GET Bucket object lock configuration.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ----------
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Gets the Object Lock configuration for a bucket. The rule specified in
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Object Lock configuration will be applied by default to every new
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// object placed in the specified bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  GetBucketObjectLockConfigHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "GetBucketObjectLockConfig" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// check if user has permissions to perform this operation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s3Error  :=  checkRequestAuthType ( ctx ,  r ,  policy . GetBucketObjectLockConfigurationAction ,  bucket ,  "" ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-02 00:53:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									config ,  _ ,  err  :=  globalBucketMetadataSys . GetObjectLockConfig ( bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 01:18:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 01:18:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									configData ,  err  :=  xml . Marshal ( config ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 04:44:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-13 06:50:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Write success response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									writeSuccessResponseXML ( w ,  configData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PutBucketTaggingHandler - PUT Bucket tagging.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ----------
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  PutBucketTaggingHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "PutBucketTagging" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-21 08:41:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket exists.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-26 08:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  err  :=  objectAPI . GetBucketInfo ( ctx ,  bucket ,  BucketOptions { } ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-21 08:41:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  s3Error  :=  checkRequestAuthType ( ctx ,  r ,  policy . PutBucketTaggingAction ,  bucket ,  "" ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 04:44:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tags ,  err  :=  tags . ParseBucketXML ( io . LimitReader ( r . Body ,  r . ContentLength ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiErr  :=  errorCodes . ToAPIErr ( ErrMalformedXML ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiErr . Description  =  err . Error ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  apiErr ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 04:44:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									configData ,  err  :=  xml . Marshal ( tags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									updatedAt ,  err  :=  globalBucketMetadataSys . Update ( ctx ,  bucket ,  bucketTaggingConfig ,  configData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Call site replication hook.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// We encode the xml bytes as base64 to ensure there are no encoding
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// errors.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfgStr  :=  base64 . StdEncoding . EncodeToString ( configData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  globalSiteReplicationSys . BucketMetaHook ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Type :       madmin . SRBucketMetaTypeTags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Tags :       & cfgStr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UpdatedAt :  updatedAt , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Write success response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									writeSuccessResponseHeadersOnly ( w ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetBucketTaggingHandler - GET Bucket tagging.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ----------
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  GetBucketTaggingHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "GetBucketTagging" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 04:44:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// check if user has permissions to perform this operation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s3Error  :=  checkRequestAuthType ( ctx ,  r ,  policy . GetBucketTaggingAction ,  bucket ,  "" ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 04:44:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-24 17:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									config ,  _ ,  err  :=  globalBucketMetadataSys . GetTaggingConfig ( bucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 01:18:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-21 01:18:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									configData ,  err  :=  xml . Marshal ( config ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 04:44:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Write success response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									writeSuccessResponseXML ( w ,  configData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// DeleteBucketTaggingHandler - DELETE Bucket tagging.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ----------
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( api  objectAPIHandlers )  DeleteBucketTaggingHandler ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "DeleteBucketTagging" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 05:21:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( ctx ,  w ,  r ,  mustGetClaimsFromToken ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectAPI  :=  api . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( ErrServerNotInitialized ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s3Error  :=  checkRequestAuthType ( ctx ,  r ,  policy . PutBucketTaggingAction ,  bucket ,  "" ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Error ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-20 08:55:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									updatedAt ,  err  :=  globalBucketMetadataSys . Delete ( ctx ,  bucket ,  bucketTaggingConfig ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-18 11:27:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  globalSiteReplicationSys . BucketMetaHook ( ctx ,  madmin . SRBucketMeta { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-29 09:09:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Type :       madmin . SRBucketMetaTypeTags , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UpdatedAt :  updatedAt , 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-07 07:36:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-06 05:18:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Write success response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									writeSuccessResponseHeadersOnly ( w ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}