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/>.
  
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-19 07:23:42 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  cmd  
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/md5" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"encoding/base64" 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/hex" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/xml" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"io/ioutil" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/http/httptest" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"path" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"runtime" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"testing" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									humanize  "github.com/dustin/go-humanize" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-02 05:59:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/auth" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xhttp  "github.com/minio/minio/internal/http" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ioutilx  "github.com/minio/minio/internal/ioutil" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Type to capture different modifications to API request to simulate failure cases.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  Fault  int  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									None  Fault  =  iota 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MissingContentLength 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									TooBigObject 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									TooBigDecodedLength 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BadSignature 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BadMD5 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									MissingUploadID 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling HeadObject API handler tests for both Erasure multiple disks and FS single drive setup.
  
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPIHeadObjectHandler ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPIHeadObjectHandler ,  [ ] string { "HeadObject" } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPIHeadObjectHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-04-14 03:00:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectName  :=  "test-object" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set of byte data for PutObject.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// object has to be created before running tests for HeadObject.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// this is required even to assert the HeadObject data,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since dataInserted === dataFetched back is a primary criteria for any object storage this assertion is critical.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bytesData  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byteData  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ generateBytesData ( 6  *  humanize . MiByte ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set of inputs for uploading the objects before tests for downloading is done.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									putObjectInputs  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										contentLength  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										textData       [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metaData       map [ string ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  int64 ( len ( bytesData [ 0 ] . byteData ) ) ,  bytesData [ 0 ] . byteData ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// iterate through the above set of inputs and upload the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  input  :=  range  putObjectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// uploading the object.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-27 14:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  :=  obj . PutObject ( context . Background ( ) ,  input . bucketName ,  input . objectName ,  mustGetPutObjReader ( t ,  bytes . NewReader ( input . textData ) ,  input . contentLength ,  input . metaData [ "" ] ,  "" ) ,  ObjectOptions { UserDefined :  input . metaData } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// if object upload fails stop the test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Put Object case %d:  Error uploading object: <ERROR> %v" ,  i + 1 ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// test cases with inputs and expected result for HeadObject.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accessKey   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										secretKey   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// expected output.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedRespStatus  int  // expected response status body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Fetching stat info of object and validating it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with non-existent object name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          "abcd" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case to induce a signature mismatch.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Using invalid accessID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           "Invalid-AccessID" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Iterating over the cases, fetching the object validating the response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  testCase  :=  range  testCases  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// construct HTTP request for Get Object end point.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  :=  newTestSignedRequestV4 ( http . MethodHead ,  getHeadObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed to create HTTP request for Head Object: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler,`func (api objectAPIHandlers) GetObjectHandler`  handles the request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Case %d: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Verify response of the V2 signed HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										recV2  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// construct HTTP request for Head Object endpoint.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reqV2 ,  err  :=  newTestSignedRequestV2 ( http . MethodHead ,  getHeadObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed to create HTTP request for Head Object: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( recV2 ,  reqV2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  recV2 . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "Test %d: %s: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  recV2 . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Test for Anonymous/unsigned http request.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( http . MethodHead ,  getHeadObjectURL ( "" ,  bucketName ,  objectName ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s: Failed to create an anonymous request for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  objectName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// unsigned request goes through and its validated again.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPIAnonTest ( t ,  obj ,  "TestAPIHeadObjectHandler" ,  bucketName ,  objectName ,  instanceType ,  apiRouter ,  anonReq ,  getAnonReadOnlyObjectPolicy ( bucketName ,  objectName ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// HTTP request for testing when `objectLayer` is set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There is no need to use an existing bucket and valid input for creating the request
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodHead ,  getGetObjectURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` manages the operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPIHeadObjectHandlerWithEncryption ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalPolicySys  =  NewPolicySys ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  {  globalPolicySys  =  nil  } ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPIHeadObjectHandlerWithEncryption ,  [ ] string { "NewMultipart" ,  "PutObjectPart" ,  "CompleteMultipart" ,  "GetObject" ,  "PutObject" ,  "HeadObject" } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPIHeadObjectHandlerWithEncryption ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set SSL to on to do encryption tests
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-22 13:42:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalIsTLS  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  {  globalIsTLS  =  false  } ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										oneMiB         int64  =  1024  *  1024 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										key32Bytes           =  generateBytesData ( 32  *  humanize . Byte ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										key32BytesMd5        =  md5 . Sum ( key32Bytes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metaWithSSEC         =  map [ string ] string { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-23 01:19:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											xhttp . AmzServerSideEncryptionCustomerAlgorithm :  xhttp . AmzEncryptionAES , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xhttp . AmzServerSideEncryptionCustomerKey :        base64 . StdEncoding . EncodeToString ( key32Bytes ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xhttp . AmzServerSideEncryptionCustomerKeyMD5 :     base64 . StdEncoding . EncodeToString ( key32BytesMd5 [ : ] ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mapCopy  =  func ( m  map [ string ] string )  map [ string ] string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r  :=  make ( map [ string ] string ,  len ( m ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  k ,  v  :=  range  m  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r [ k ]  =  v 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  r 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  ObjectInput  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										partLengths  [ ] int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metaData  map [ string ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectLength  :=  func ( oi  ObjectInput )  ( sum  int64 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  l  :=  range  oi . partLengths  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sum  +=  l 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set of inputs for uploading the objects before tests for
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// downloading is done. Data bytes are from DummyDataGen.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectInputs  :=  [ ] ObjectInput { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Unencrypted objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "nothing" ,  [ ] int64 { 0 } ,  nil } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "small-1" ,  [ ] int64 { 509 } ,  nil } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "mp-1" ,  [ ] int64 { 5  *  oneMiB ,  1 } ,  nil } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "mp-2" ,  [ ] int64 { 5487701 ,  5487799 ,  3 } ,  nil } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Encrypted object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-nothing" ,  [ ] int64 { 0 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-small-1" ,  [ ] int64 { 509 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-mp-1" ,  [ ] int64 { 5  *  oneMiB ,  1 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-mp-2" ,  [ ] int64 { 5487701 ,  5487799 ,  3 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// iterate through the above set of inputs and upload the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  input  :=  range  objectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uploadTestObject ( t ,  apiRouter ,  credentials ,  bucketName ,  input . objectName ,  input . partLengths ,  input . metaData ,  false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  input  :=  range  objectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// construct HTTP request for HEAD object.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  :=  newTestSignedRequestV4 ( http . MethodHead ,  getHeadObjectURL ( "" ,  bucketName ,  input . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed to create HTTP request for Head Object: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										isEnc  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expected  :=  200 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  strings . HasPrefix ( input . objectName ,  "enc-" )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											isEnc  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expected  =  400 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  expected  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "Test %d: expected code %d but got %d for object %s" ,  i + 1 ,  expected ,  rec . Code ,  input . objectName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										contentLength  :=  rec . Header ( ) . Get ( "Content-Length" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  isEnc  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// initialize HTTP NewRecorder, this records any
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// construct HTTP request for HEAD object.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req ,  err  :=  newTestSignedRequestV4 ( http . MethodHead ,  getHeadObjectURL ( "" ,  bucketName ,  input . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  input . metaData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Failed to create HTTP request for Head Object: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Since `apiRouter` satisfies `http.Handler` it has a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  rec . Code  !=  200  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "Test %d: Did not receive a 200 response: %d" ,  i + 1 ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											contentLength  =  rec . Header ( ) . Get ( "Content-Length" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  contentLength  !=  fmt . Sprintf ( "%d" ,  objectLength ( input ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "Test %d: Content length is mismatching: got %s (expected: %d)" ,  i + 1 ,  contentLength ,  objectLength ( input ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling GetObject API handler tests for both Erasure multiple disks and FS single drive setup.
  
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPIGetObjectHandler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalPolicySys  =  NewPolicySys ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  {  globalPolicySys  =  nil  } ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecExtendedObjectLayerAPITest ( t ,  testAPIGetObjectHandler ,  [ ] string { "GetObject" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  testAPIGetObjectHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									objectName  :=  "test-object" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set of byte data for PutObject.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// object has to be created before running tests for GetObject.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// this is required even to assert the GetObject data,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since dataInserted === dataFetched back is a primary criteria for any object storage this assertion is critical.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bytesData  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byteData  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ generateBytesData ( 6  *  humanize . MiByte ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set of inputs for uploading the objects before tests for downloading is done.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									putObjectInputs  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										contentLength  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										textData       [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metaData       map [ string ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  int64 ( len ( bytesData [ 0 ] . byteData ) ) ,  bytesData [ 0 ] . byteData ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// iterate through the above set of inputs and upload the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  input  :=  range  putObjectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// uploading the object.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-27 14:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  :=  obj . PutObject ( context . Background ( ) ,  input . bucketName ,  input . objectName ,  mustGetPutObjReader ( t ,  bytes . NewReader ( input . textData ) ,  input . contentLength ,  input . metaData [ "" ] ,  "" ) ,  ObjectOptions { UserDefined :  input . metaData } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// if object upload fails stop the test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Put Object case %d:  Error uploading object: <ERROR> %v" ,  i + 1 ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  context . Background ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// test cases with inputs and expected result for GetObject.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byteRange   string  // range of bytes to be fetched from GetObject.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accessKey   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										secretKey   string 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// expected output.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedContent     [ ] byte  // expected response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedRespStatus  int     // expected response status body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Fetching the entire object and validating its contents.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedContent :     bytesData [ 0 ] . byteData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with non-existent object name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  "abcd" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getAPIError ( ErrNoSuchKey ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  "abcd" ) ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Requesting from range 10-100.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "bytes=10-100" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedContent :     bytesData [ 0 ] . byteData [ 10 : 101 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusPartialContent , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with invalid range.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "bytes=-0" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getAPIError ( ErrInvalidRange ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusRequestedRangeNotSatisfiable , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 5.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with byte range exceeding the object size.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Expected to read till end of the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "bytes=10-1000000000000000" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedContent :     bytesData [ 0 ] . byteData [ 10 : ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusPartialContent , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 6.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case to induce a signature mismatch.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Using invalid accessID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :   "Invalid-AccessID" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getAPIError ( ErrInvalidAccessKeyID ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-25 09:13:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 7.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with bad components in object name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  "../../etc" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getAPIError ( ErrInvalidObjectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  "../../etc" ) ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-25 09:13:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 8.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with strange components but returning error as not found.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  ". ./. ./etc" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getAPIError ( ErrNoSuchKey ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												SlashSeparator + bucketName + SlashSeparator + ". ./. ./etc" ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-25 09:13:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 9.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with bad components in object name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  ". ./../etc" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getAPIError ( ErrInvalidObjectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												SlashSeparator + bucketName + SlashSeparator + ". ./../etc" ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-25 09:13:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 10.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with proper components
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  "etc/path/proper/.../etc" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getAPIError ( ErrNoSuchKey ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  "etc/path/proper/.../etc" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-25 09:13:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Iterating over the cases, fetching the object validating the response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  testCase  :=  range  testCases  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// construct HTTP request for Get Object end point.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  :=  newTestSignedRequestV4 ( http . MethodGet ,  getGetObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: Failed to create HTTP request for Get Object: <ERROR> %v" ,  i + 1 ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . byteRange  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-02 07:58:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req . Header . Set ( "Range" ,  testCase . byteRange ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler,`func (api objectAPIHandlers) GetObjectHandler`  handles the request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Case %d: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// read the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										actualContent ,  err  :=  ioutil . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed reading response body: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  ==  http . StatusOK  ||  rec . Code  ==  http . StatusPartialContent  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! bytes . Equal ( testCase . expectedContent ,  actualContent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "Test %d: %s: Object content differs from expected value %s, got %s" ,  i + 1 ,  instanceType ,  testCase . expectedContent ,  string ( actualContent ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Verify whether the bucket obtained object is same as the one created.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										actualError  :=  & APIErrorResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  xml . Unmarshal ( actualContent ,  actualError ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed parsing response body: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-08 13:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  path . Clean ( actualError . Resource )  !=  pathJoin ( SlashSeparator ,  testCase . bucketName ,  testCase . objectName )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Unexpected resource, expected %s, got %s" ,  i + 1 ,  instanceType ,  pathJoin ( SlashSeparator ,  testCase . bucketName ,  testCase . objectName ) ,  actualError . Resource ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Verify response of the V2 signed HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										recV2  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// construct HTTP request for  GET Object endpoint.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reqV2 ,  err  :=  newTestSignedRequestV2 ( http . MethodGet ,  getGetObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed to create HTTP request for GetObject: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . byteRange  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-02 07:58:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reqV2 . Header . Set ( "Range" ,  testCase . byteRange ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( recV2 ,  reqV2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  recV2 . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "Test %d: %s: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  recV2 . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// read the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										actualContent ,  err  =  ioutil . ReadAll ( recV2 . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed to read response body: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  ==  http . StatusOK  ||  rec . Code  ==  http . StatusPartialContent  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Verify whether the bucket obtained object is same as the one created.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! bytes . Equal ( testCase . expectedContent ,  actualContent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "Test %d: %s: Object content differs from expected value." ,  i + 1 ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										actualError  =  & APIErrorResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  xml . Unmarshal ( actualContent ,  actualError ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed parsing response body: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-08 13:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  path . Clean ( actualError . Resource )  !=  pathJoin ( SlashSeparator ,  testCase . bucketName ,  testCase . objectName )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Unexpected resource, expected %s, got %s" ,  i + 1 ,  instanceType ,  pathJoin ( SlashSeparator ,  testCase . bucketName ,  testCase . objectName ) ,  actualError . Resource ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Test for Anonymous/unsigned http request.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( http . MethodGet ,  getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s: Failed to create an anonymous request for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  objectName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// unsigned request goes through and its validated again.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPIAnonTest ( t ,  obj ,  "TestAPIGetObjectHandler" ,  bucketName ,  objectName ,  instanceType ,  apiRouter ,  anonReq ,  getAnonReadOnlyObjectPolicy ( bucketName ,  objectName ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HTTP request for testing when `objectLayer` is set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There is no need to use an existing bucket and valid input for creating the request
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodGet ,  getGetObjectURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` manages the operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling GetObject API handler tests for both Erasure multiple disks and FS single drive setup.
  
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPIGetObjectWithMPHandler ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalPolicySys  =  NewPolicySys ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  {  globalPolicySys  =  nil  } ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecExtendedObjectLayerAPITest ( t ,  testAPIGetObjectWithMPHandler ,  [ ] string { "NewMultipart" ,  "PutObjectPart" ,  "CompleteMultipart" ,  "GetObject" ,  "PutObject" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPIGetObjectWithMPHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set SSL to on to do encryption tests
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-22 13:42:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalIsTLS  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  {  globalIsTLS  =  false  } ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										oneMiB         int64  =  1024  *  1024 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										key32Bytes           =  generateBytesData ( 32  *  humanize . Byte ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										key32BytesMd5        =  md5 . Sum ( key32Bytes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metaWithSSEC         =  map [ string ] string { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-23 01:19:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											xhttp . AmzServerSideEncryptionCustomerAlgorithm :  xhttp . AmzEncryptionAES , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xhttp . AmzServerSideEncryptionCustomerKey :        base64 . StdEncoding . EncodeToString ( key32Bytes ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xhttp . AmzServerSideEncryptionCustomerKeyMD5 :     base64 . StdEncoding . EncodeToString ( key32BytesMd5 [ : ] ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mapCopy  =  func ( m  map [ string ] string )  map [ string ] string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r  :=  make ( map [ string ] string ,  len ( m ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  k ,  v  :=  range  m  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r [ k ]  =  v 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  r 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  ObjectInput  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										partLengths  [ ] int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metaData  map [ string ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectLength  :=  func ( oi  ObjectInput )  ( sum  int64 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  l  :=  range  oi . partLengths  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sum  +=  l 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set of inputs for uploading the objects before tests for
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// downloading is done. Data bytes are from DummyDataGen.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectInputs  :=  [ ] ObjectInput { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// // cases 0-3: small single part objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "nothing" ,  [ ] int64 { 0 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "small-0" ,  [ ] int64 { 11 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "small-1" ,  [ ] int64 { 509 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "small-2" ,  [ ] int64 { 5  *  oneMiB } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// // // cases 4-7: multipart part objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "mp-0" ,  [ ] int64 { 5  *  oneMiB ,  1 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "mp-1" ,  [ ] int64 { 5 * oneMiB  +  1 ,  1 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "mp-2" ,  [ ] int64 { 5487701 ,  5487799 ,  3 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "mp-3" ,  [ ] int64 { 10499807 ,  10499963 ,  7 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// cases 8-11: small single part objects with encryption
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-nothing" ,  [ ] int64 { 0 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-small-0" ,  [ ] int64 { 11 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-small-1" ,  [ ] int64 { 509 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-small-2" ,  [ ] int64 { 5  *  oneMiB } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// cases 12-15: multipart part objects with encryption
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-mp-0" ,  [ ] int64 { 5  *  oneMiB ,  1 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-mp-1" ,  [ ] int64 { 5 * oneMiB  +  1 ,  1 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-mp-2" ,  [ ] int64 { 5487701 ,  5487799 ,  3 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-mp-3" ,  [ ] int64 { 10499807 ,  10499963 ,  7 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// iterate through the above set of inputs and upload the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  input  :=  range  objectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uploadTestObject ( t ,  apiRouter ,  credentials ,  bucketName ,  input . objectName ,  input . partLengths ,  input . metaData ,  false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// function type for creating signed requests - used to repeat
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// requests with V2 and V4 signing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  testSignedReqFn  func ( method ,  urlStr  string ,  contentLength  int64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										body  io . ReadSeeker ,  accessKey ,  secretKey  string ,  metamap  map [ string ] string )  ( * http . Request , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										error ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mkGetReq  :=  func ( oi  ObjectInput ,  byteRange  string ,  i  int ,  mkSignedReq  testSignedReqFn )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										object  :=  oi . objectName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  :=  mkSignedReq ( http . MethodGet ,  getGetObjectURL ( "" ,  bucketName ,  object ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  oi . metaData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Object: %s Case %d ByteRange: %s: Failed to create HTTP request for Get Object: <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												object ,  i + 1 ,  byteRange ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  byteRange  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-02 07:58:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req . Header . Set ( "Range" ,  byteRange ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Check response code (we make only valid requests in
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// this test)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  http . StatusPartialContent  &&  rec . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bd ,  err1  :=  ioutil . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "%s Object: %s Case %d ByteRange: %s: Got response status `%d` and body: %s,%v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												instanceType ,  object ,  i + 1 ,  byteRange ,  rec . Code ,  string ( bd ) ,  err1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  off ,  length  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  rs  * HTTPRangeSpec 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  byteRange  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rs ,  err  =  parseRequestRangeSpec ( byteRange ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Object: %s Case %d ByteRange: %s: Unexpected err: %v" ,  object ,  i + 1 ,  byteRange ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										off ,  length ,  err  =  rs . GetOffsetLength ( objectLength ( oi ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Object: %s Case %d ByteRange: %s: Unexpected err: %v" ,  object ,  i + 1 ,  byteRange ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										readers  :=  [ ] io . Reader { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cumulativeSum  :=  int64 ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  p  :=  range  oi . partLengths  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											readers  =  append ( readers ,  NewDummyDataGen ( p ,  cumulativeSum ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cumulativeSum  +=  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										refReader  :=  io . LimitReader ( ioutilx . NewSkipReader ( io . MultiReader ( readers ... ) ,  off ) ,  length ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ok ,  msg  :=  cmpReaders ( refReader ,  rec . Body ) ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "(%s) Object: %s Case %d ByteRange: %s --> data mismatch! (msg: %s)" ,  instanceType ,  oi . objectName ,  i + 1 ,  byteRange ,  msg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Iterate over each uploaded object and do a bunch of get
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// requests on them.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									caseNumber  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signFns  :=  [ ] testSignedReqFn { newTestSignedRequestV2 ,  newTestSignedRequestV4 } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  oi  :=  range  objectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objLen  :=  objectLength ( oi ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  sf  :=  range  signFns  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Read whole object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mkGetReq ( oi ,  "" ,  caseNumber ,  sf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											caseNumber ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// No range requests are possible if the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// object length is 0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  objLen  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Various ranges to query - all are valid!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rangeHdrs  :=  [ ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Read first byte of object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fmt . Sprintf ( "bytes=%d-%d" ,  0 ,  0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Read second byte of object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fmt . Sprintf ( "bytes=%d-%d" ,  1 ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Read last byte of object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fmt . Sprintf ( "bytes=-%d" ,  1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Read all but first byte of object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"bytes=1-" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Read first half of object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fmt . Sprintf ( "bytes=%d-%d" ,  0 ,  objLen / 2 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Read last half of object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fmt . Sprintf ( "bytes=-%d" ,  objLen / 2 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Read middle half of object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fmt . Sprintf ( "bytes=%d-%d" ,  objLen / 4 ,  objLen * 3 / 4 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Read 100MiB of the object from the beginning
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fmt . Sprintf ( "bytes=%d-%d" ,  0 ,  100 * humanize . MiByte ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Read 100MiB of the object from the end
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fmt . Sprintf ( "bytes=-%d" ,  100 * humanize . MiByte ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  rangeHdr  :=  range  rangeHdrs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mkGetReq ( oi ,  rangeHdr ,  caseNumber ,  sf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												caseNumber ++ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// HTTP request for testing when `objectLayer` is set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There is no need to use an existing bucket and valid input for creating the request
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodGet ,  getGetObjectURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` manages the operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 05:12:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling GetObject API handler tests for both Erasure multiple disks and FS single drive setup.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPIGetObjectWithPartNumberHandler ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalPolicySys  =  NewPolicySys ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  {  globalPolicySys  =  nil  } ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecExtendedObjectLayerAPITest ( t ,  testAPIGetObjectWithPartNumberHandler ,  [ ] string { "NewMultipart" ,  "PutObjectPart" ,  "CompleteMultipart" ,  "GetObject" ,  "PutObject" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 05:12:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPIGetObjectWithPartNumberHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2020-12-09 05:12:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set SSL to on to do encryption tests
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-22 13:42:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalIsTLS  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  func ( )  {  globalIsTLS  =  false  } ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 05:12:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										oneMiB         int64  =  1024  *  1024 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										key32Bytes           =  generateBytesData ( 32  *  humanize . Byte ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										key32BytesMd5        =  md5 . Sum ( key32Bytes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metaWithSSEC         =  map [ string ] string { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-23 01:19:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											xhttp . AmzServerSideEncryptionCustomerAlgorithm :  xhttp . AmzEncryptionAES , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xhttp . AmzServerSideEncryptionCustomerKey :        base64 . StdEncoding . EncodeToString ( key32Bytes ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											xhttp . AmzServerSideEncryptionCustomerKeyMD5 :     base64 . StdEncoding . EncodeToString ( key32BytesMd5 [ : ] ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 05:12:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mapCopy  =  func ( m  map [ string ] string )  map [ string ] string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r  :=  make ( map [ string ] string ,  len ( m ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  k ,  v  :=  range  m  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r [ k ]  =  v 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  r 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  ObjectInput  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										partLengths  [ ] int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metaData  map [ string ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set of inputs for uploading the objects before tests for
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// downloading is done. Data bytes are from DummyDataGen.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectInputs  :=  [ ] ObjectInput { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// // cases 0-4: small single part objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "nothing" ,  [ ] int64 { 0 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "1byte" ,  [ ] int64 { 1 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "small-0" ,  [ ] int64 { 11 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "small-1" ,  [ ] int64 { 509 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "small-2" ,  [ ] int64 { 5  *  oneMiB } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// // // cases 5-8: multipart part objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "mp-0" ,  [ ] int64 { 5  *  oneMiB ,  1 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "mp-1" ,  [ ] int64 { 5 * oneMiB  +  1 ,  1 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "mp-2" ,  [ ] int64 { 5487701 ,  5487799 ,  3 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "mp-3" ,  [ ] int64 { 10499807 ,  10499963 ,  7 } ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// cases 9-12: small single part objects with encryption
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-nothing" ,  [ ] int64 { 0 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-small-0" ,  [ ] int64 { 11 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-small-1" ,  [ ] int64 { 509 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-small-2" ,  [ ] int64 { 5  *  oneMiB } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// cases 13-16: multipart part objects with encryption
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-mp-0" ,  [ ] int64 { 5  *  oneMiB ,  1 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-mp-1" ,  [ ] int64 { 5 * oneMiB  +  1 ,  1 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-mp-2" ,  [ ] int64 { 5487701 ,  5487799 ,  3 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ "enc-mp-3" ,  [ ] int64 { 10499807 ,  10499963 ,  7 } ,  mapCopy ( metaWithSSEC ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// iterate through the above set of inputs and upload the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  input  :=  range  objectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uploadTestObject ( t ,  apiRouter ,  credentials ,  bucketName ,  input . objectName ,  input . partLengths ,  input . metaData ,  false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mkGetReqWithPartNumber  :=  func ( oindex  int ,  oi  ObjectInput ,  partNumber  int )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										object  :=  oi . objectName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queries  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queries . Add ( "partNumber" ,  strconv . Itoa ( partNumber ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										targetURL  :=  makeTestTargetURL ( "" ,  bucketName ,  object ,  queries ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req ,  err  :=  newTestSignedRequestV4 ( http . MethodGet ,  targetURL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  oi . metaData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Object: %s Object Index %d PartNumber: %d: Failed to create HTTP request for Get Object: <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												object ,  oindex ,  partNumber ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-08 13:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 05:12:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Check response code (we make only valid requests in this test)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  http . StatusPartialContent  &&  rec . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bd ,  err1  :=  ioutil . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "%s Object: %s ObjectIndex %d PartNumber: %d: Got response status `%d` and body: %s,%v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												instanceType ,  object ,  oindex ,  partNumber ,  rec . Code ,  string ( bd ) ,  err1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										oinfo ,  err  :=  obj . GetObjectInfo ( context . Background ( ) ,  bucketName ,  object ,  ObjectOptions { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Object: %s Object Index %d: Unexpected err: %v" ,  object ,  oindex ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rs  :=  partNumberToRangeSpec ( oinfo ,  partNumber ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										size ,  err  :=  oinfo . GetActualSize ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Object: %s Object Index %d: Unexpected err: %v" ,  object ,  oindex ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										off ,  length ,  err  :=  rs . GetOffsetLength ( size ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 05:12:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Object: %s Object Index %d: Unexpected err: %v" ,  object ,  oindex ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										readers  :=  [ ] io . Reader { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cumulativeSum  :=  int64 ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  p  :=  range  oi . partLengths  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											readers  =  append ( readers ,  NewDummyDataGen ( p ,  cumulativeSum ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cumulativeSum  +=  p 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 05:12:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										refReader  :=  io . LimitReader ( ioutilx . NewSkipReader ( io . MultiReader ( readers ... ) ,  off ) ,  length ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ok ,  msg  :=  cmpReaders ( refReader ,  rec . Body ) ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "(%s) Object: %s ObjectIndex %d PartNumber: %d --> data mismatch! (msg: %s)" ,  instanceType ,  oi . objectName ,  oindex ,  partNumber ,  msg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  idx ,  oi  :=  range  objectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  partNum  :=  1 ;  partNum  <=  len ( oi . partLengths ) ;  partNum ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											mkGetReqWithPartNumber ( idx ,  oi ,  partNum ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling PutObject API handler tests using streaming signature v4 for both Erasure multiple disks and FS single drive setup.
  
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPIPutObjectStreamSigV4Handler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecExtendedObjectLayerAPITest ( t ,  testAPIPutObjectStreamSigV4Handler ,  [ ] string { "PutObject" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  testAPIPutObjectStreamSigV4Handler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectName  :=  "test-object" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bytesDataLen  :=  65  *  humanize . KiByte 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bytesData  :=  bytes . Repeat ( [ ] byte { 'a' } ,  bytesDataLen ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									oneKData  :=  bytes . Repeat ( [ ] byte ( "a" ) ,  1 * humanize . KiByte ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  streamFault  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										None  streamFault  =  iota 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										malformedEncoding 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unexpectedEOF 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										signatureMismatch 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										chunkDateMismatch 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tooBigDecodedLength 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// byte data for PutObject.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// test cases with inputs and expected result for GetObject.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										data        [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dataLen     int 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										chunkSize   int64 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// expected output.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedContent     [ ] byte  // expected response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedRespStatus  int     // expected response status body.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Access keys
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accessKey         string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										secretKey         string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										shouldPass        bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										removeAuthHeader  bool 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										fault             streamFault 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 08:02:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Custom content encoding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										contentEncoding  string 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Fetching the entire object and validating its contents.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             len ( bytesData ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											chunkSize :           64  *  humanize . KiByte , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											shouldPass :          true , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 20:59:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fault :               None , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 2
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Small chunk size.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             len ( bytesData ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											chunkSize :           1  *  humanize . KiByte , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											shouldPass :          true , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 20:59:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fault :               None , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 3
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 06:19:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Empty data
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                [ ] byte { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chunkSize :           64  *  humanize . KiByte , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											shouldPass :          true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 4
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Invalid access key id.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             len ( bytesData ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											chunkSize :           64  *  humanize . KiByte , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											shouldPass :          false , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 20:59:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fault :               None , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 06:19:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 5
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Wrong auth header returns as bad request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             len ( bytesData ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											chunkSize :           64  *  humanize . KiByte , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											shouldPass :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											removeAuthHeader :    true , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 20:59:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fault :               None , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 06:19:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 6
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Large chunk size.. also passes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             len ( bytesData ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											chunkSize :           100  *  humanize . KiByte , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 08:02:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											shouldPass :          true , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 20:59:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fault :               None , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 06:19:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 7
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Chunk with malformed encoding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                oneKData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             1024 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chunkSize :           1024 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 05:37:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											shouldPass :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :               malformedEncoding , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 06:19:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 8
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Chunk with shorter than advertised chunk data.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                oneKData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             1024 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chunkSize :           1024 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											shouldPass :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :               unexpectedEOF , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 06:19:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 9
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Chunk with first chunk data byte tampered.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                oneKData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             1024 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chunkSize :           1024 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusForbidden , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											shouldPass :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :               signatureMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 06:19:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 10
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Different date (timestamps) used in seed signature calculation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// and chunks signature calculation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                oneKData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             1024 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chunkSize :           1024 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusForbidden , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											shouldPass :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :               chunkDateMismatch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 06:19:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 11
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Set x-amz-decoded-content-length to a value too big to hold in int64.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                oneKData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             1024 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chunkSize :           1024 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 05:37:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											shouldPass :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :               tooBigDecodedLength , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 08:02:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 12
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Set custom content encoding should succeed and save the encoding properly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             len ( bytesData ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chunkSize :           100  *  humanize . KiByte , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :     [ ] byte { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											shouldPass :          true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											contentEncoding :     "aws-chunked,gzip" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 20:59:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fault :               None , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 08:02:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Iterating over the cases, fetching the object validating the response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  testCase  :=  range  testCases  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// construct HTTP request for Put Object end point.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  req  * http . Request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . fault  ==  chunkDateMismatch  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req ,  err  =  newTestStreamingSignedBadChunkDateRequest ( http . MethodPut , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getPutObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												int64 ( testCase . dataLen ) ,  testCase . chunkSize ,  bytes . NewReader ( testCase . data ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 08:02:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  testCase . contentEncoding  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req ,  err  =  newTestStreamingSignedRequest ( http . MethodPut , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getPutObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												int64 ( testCase . dataLen ) ,  testCase . chunkSize ,  bytes . NewReader ( testCase . data ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 08:02:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  testCase . contentEncoding  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req ,  err  =  newTestStreamingSignedCustomEncodingRequest ( http . MethodPut , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 08:02:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getPutObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												int64 ( testCase . dataLen ) ,  testCase . chunkSize ,  bytes . NewReader ( testCase . data ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												testCase . accessKey ,  testCase . secretKey ,  testCase . contentEncoding ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: Failed to create HTTP request for Put Object: <ERROR> %v" ,  i + 1 ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Removes auth header if test case requires it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . removeAuthHeader  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Del ( "Authorization" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										switch  testCase . fault  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  malformedEncoding : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req ,  err  =  malformChunkSizeSigV4 ( req ,  testCase . chunkSize - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  signatureMismatch : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req ,  err  =  malformDataSigV4 ( req ,  'z' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  unexpectedEOF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req ,  err  =  truncateChunkByHalfSigv4 ( req ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  tooBigDecodedLength : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Set decoded length to a large value out of int64 range to simulate parse failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( "x-amz-decoded-content-length" ,  "9999999999999999999999" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-31 14:32:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Error injecting faults into the request: <ERROR> %v." ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler,`func (api objectAPIHandlers) GetObjectHandler`  handles the request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "Test %d %s: Expected the response status to be `%d`, but instead found `%d`: fault case %d" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  rec . Code ,  testCase . fault ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// read the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										actualContent ,  err  :=  ioutil . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed parsing response body: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 00:42:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										opts  :=  ObjectOptions { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  testCase . shouldPass  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Verify whether the bucket obtained object is same as the one created.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! bytes . Equal ( testCase . expectedContent ,  actualContent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "Test %d: %s: Object content differs from expected value.: %s" ,  i + 1 ,  instanceType ,  string ( actualContent ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 00:42:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objInfo ,  err  :=  obj . GetObjectInfo ( context . Background ( ) ,  testCase . bucketName ,  testCase . objectName ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-21 04:07:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Failed to fetch the copied object: <ERROR> %s" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  objInfo . ContentEncoding  ==  streamingContentEncoding  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: ContentEncoding is set to \"aws-chunked\" which is unexpected" ,  i + 1 ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 08:02:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContentEncoding  :=  trimAwsChunkedContentEncoding ( testCase . contentEncoding ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  expectedContentEncoding  !=  objInfo . ContentEncoding  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: ContentEncoding is set to \"%s\" which is unexpected, expected \"%s\"" ,  i + 1 ,  instanceType ,  objInfo . ContentEncoding ,  expectedContentEncoding ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											buffer  :=  new ( bytes . Buffer ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r ,  err  :=  obj . GetObjectNInfo ( context . Background ( ) ,  testCase . bucketName ,  testCase . objectName ,  nil ,  nil ,  readLock ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Failed to fetch the copied object: <ERROR> %s" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  =  io . Copy ( buffer ,  r ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Failed to fetch the copied object: <ERROR> %s" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 06:19:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! bytes . Equal ( testCase . data ,  buffer . Bytes ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t . Errorf ( "Test %d: %s: Data Mismatch: Data fetched back from the uploaded object doesn't match the original one." ,  i + 1 ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling PutObject API handler tests for both Erasure multiple disks and FS single drive setup.
  
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPIPutObjectHandler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecExtendedObjectLayerAPITest ( t ,  testAPIPutObjectHandler ,  [ ] string { "PutObject" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  testAPIPutObjectHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectName  :=  "test-object" 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 00:42:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									opts  :=  ObjectOptions { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// byte data for PutObject.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bytesData  :=  generateBytesData ( 6  *  humanize . KiByte ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									copySourceHeader  :=  http . Header { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									copySourceHeader . Set ( "X-Amz-Copy-Source" ,  "somewhere" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									invalidMD5Header  :=  http . Header { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									invalidMD5Header . Set ( "Content-Md5" ,  "42" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-27 12:36:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									inalidStorageClassHeader  :=  http . Header { } 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-07 13:50:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									inalidStorageClassHeader . Set ( xhttp . AmzStorageClass ,  "INVALID" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addCustomHeaders  :=  func ( req  * http . Request ,  customHeaders  http . Header )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  k ,  values  :=  range  customHeaders  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  value  :=  range  values  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												req . Header . Set ( k ,  value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// test cases with inputs and expected result for GetObject.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName  string 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										headers     http . Header 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										data        [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dataLen     int 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accessKey   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										secretKey   string 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										fault       Fault 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// expected output.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										expectedRespStatus  int  // expected response status body.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Fetching the entire object and validating its contents.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :        bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :     len ( bytesData ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test Case with invalid accessID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :        bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :     len ( bytesData ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :   "Wrong-AcessID" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test Case with invalid header key X-Amz-Copy-Source.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											headers :             copySourceHeader , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             len ( bytesData ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test Case with invalid Content-Md5 value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											headers :             invalidMD5Header , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             len ( bytesData ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 5.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test Case with object greater than maximum allowed size.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             len ( bytesData ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fault :               TooBigObject , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 6.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test Case with missing content length
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             len ( bytesData ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fault :               MissingContentLength , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusLengthRequired , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-27 12:36:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 7.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test Case with invalid header key X-Amz-Storage-Class
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :          objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											headers :             inalidStorageClassHeader , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data :                bytesData , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dataLen :             len ( bytesData ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Iterating over the cases, fetching the object validating the response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  testCase  :=  range  testCases  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  req ,  reqV2  * http . Request 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// construct HTTP request for Get Object end point.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( http . MethodPut ,  getPutObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int64 ( testCase . dataLen ) ,  bytes . NewReader ( testCase . data ) ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: Failed to create HTTP request for Put Object: <ERROR> %v" ,  i + 1 ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Add test case specific headers to the request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										addCustomHeaders ( req ,  testCase . headers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Inject faults if specified in testCase.fault
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  testCase . fault  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  MissingContentLength : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . ContentLength  =  - 1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . TransferEncoding  =  [ ] string { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  TooBigObject : 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 02:14:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req . ContentLength  =  globalMaxObjectSize  +  1 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler,`func (api objectAPIHandlers) GetObjectHandler`  handles the request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Case %d: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  testCase . expectedRespStatus  ==  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buffer  :=  new ( bytes . Buffer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Fetch the object to check whether the content is same as the one uploaded via PutObject.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											gr ,  err  :=  obj . GetObjectNInfo ( context . Background ( ) ,  testCase . bucketName ,  testCase . objectName ,  nil ,  nil ,  readLock ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Failed to fetch the copied object: <ERROR> %s" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  =  io . Copy ( buffer ,  gr ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												gr . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Failed to fetch the copied object: <ERROR> %s" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											gr . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! bytes . Equal ( bytesData ,  buffer . Bytes ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "Test %d: %s: Data Mismatch: Data fetched back from the uploaded object doesn't match the original one." ,  i + 1 ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buffer . Reset ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Verify response of the V2 signed HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										recV2  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// construct HTTP request for PUT Object endpoint.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reqV2 ,  err  =  newTestSignedRequestV2 ( http . MethodPut ,  getPutObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int64 ( testCase . dataLen ) ,  bytes . NewReader ( testCase . data ) ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed to create HTTP request for PutObject: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Add test case specific headers to the request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										addCustomHeaders ( reqV2 ,  testCase . headers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Inject faults if specified in testCase.fault
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  testCase . fault  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  MissingContentLength : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . ContentLength  =  - 1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . TransferEncoding  =  [ ] string { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  TooBigObject : 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 02:14:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reqV2 . ContentLength  =  globalMaxObjectSize  +  1 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:06:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( recV2 ,  reqV2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  recV2 . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "Test %d: %s: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  recV2 . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . expectedRespStatus  ==  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buffer  :=  new ( bytes . Buffer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Fetch the object to check whether the content is same as the one uploaded via PutObject.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											gr ,  err  :=  obj . GetObjectNInfo ( context . Background ( ) ,  testCase . bucketName ,  testCase . objectName ,  nil ,  nil ,  readLock ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Failed to fetch the copied object: <ERROR> %s" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  _ ,  err  =  io . Copy ( buffer ,  gr ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												gr . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Failed to fetch the copied object: <ERROR> %s" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											gr . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! bytes . Equal ( bytesData ,  buffer . Bytes ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "Test %d: %s: Data Mismatch: Data fetched back from the uploaded object doesn't match the original one." ,  i + 1 ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buffer . Reset ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Test for Anonymous/unsigned http request.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( http . MethodPut ,  getPutObjectURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int64 ( len ( "hello" ) ) ,  bytes . NewReader ( [ ] byte ( "hello" ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s: Failed to create an anonymous request for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  objectName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// unsigned request goes through and its validated again.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPIAnonTest ( t ,  obj ,  "TestAPIPutObjectHandler" ,  bucketName ,  objectName ,  instanceType ,  apiRouter ,  anonReq ,  getAnonWriteOnlyObjectPolicy ( bucketName ,  objectName ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HTTP request to test the case of `objectLayer` being set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There is no need to use an existing bucket or valid input for creating the request,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodPut ,  getPutObjectURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` manages the operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Tests sanity of attempting to copying each parts at offsets from an existing
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// file and create a new object. Also validates if the written is same as what we
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// expected.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPICopyObjectPartHandlerSanity ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecExtendedObjectLayerAPITest ( t ,  testAPICopyObjectPartHandlerSanity ,  [ ] string { "CopyObjectPart" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPICopyObjectPartHandlerSanity ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectName  :=  "test-object" 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 00:42:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									opts  :=  ObjectOptions { } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// set of byte data for PutObject.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// object has to be created before running tests for Copy Object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// this is required even to assert the copied object,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bytesData  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byteData  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ generateBytesData ( 6  *  humanize . MiByte ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set of inputs for uploading the objects before tests for downloading is done.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									putObjectInputs  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										contentLength  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										textData       [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metaData       map [ string ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  int64 ( len ( bytesData [ 0 ] . byteData ) ) ,  bytesData [ 0 ] . byteData ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// iterate through the above set of inputs and upload the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  input  :=  range  putObjectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// uploading the object.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  obj . PutObject ( context . Background ( ) ,  input . bucketName ,  input . objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-27 14:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											mustGetPutObjReader ( t ,  bytes . NewReader ( input . textData ) ,  input . contentLength ,  input . metaData [ "" ] ,  "" ) ,  ObjectOptions { UserDefined :  input . metaData } ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// if object upload fails stop the test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Put Object case %d:  Error uploading object: <ERROR> %v" ,  i + 1 ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Initiate Multipart upload for testing PutObjectPartHandler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testObject  :=  "testobject" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// PutObjectPart API HTTP Handler has to be tested in isolation,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// that is without any other handler being registered,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// That's why NewMultipartUpload is initiated using ObjectLayer.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 13:31:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uploadID ,  err  :=  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  testObject ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s : <ERROR>  %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a  :=  0 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									b  :=  globalMinPartSize 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  parts  [ ] CompletePart 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  partNumber  :=  1 ;  partNumber  <=  2 ;  partNumber ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cpPartURL  :=  getCopyObjectPartURL ( "" ,  bucketName ,  testObject ,  uploadID ,  fmt . Sprintf ( "%d" ,  partNumber ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// construct HTTP request for copy object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  req  * http . Request 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( http . MethodPut ,  cpPartURL ,  0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test failed to create HTTP request for copy object part: <ERROR> %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// "X-Amz-Copy-Source" header contains the information about the source bucket and the object to copied.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Header . Set ( "X-Amz-Copy-Source" ,  url . QueryEscape ( pathJoin ( bucketName ,  objectName ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Header . Set ( "X-Amz-Copy-Source-Range" ,  fmt . Sprintf ( "bytes=%d-%d" ,  a ,  b ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler, `func (api objectAPIHandlers) CopyObjectHandler` handles the request.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										a  =  globalMinPartSize  +  1 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										b  =  len ( bytesData [ 0 ] . byteData )  -  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test failed to create HTTP request for copy %d" ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  :=  & CopyObjectPartResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  xmlDecoder ( rec . Body ,  resp ,  rec . Result ( ) . ContentLength ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test failed to decode XML response: <ERROR> %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										parts  =  append ( parts ,  CompletePart { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											PartNumber :  partNumber , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-16 11:48:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ETag :        canonicalizeETag ( resp . ETag ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-15 09:36:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									result ,  err  :=  obj . CompleteMultipartUpload ( context . Background ( ) ,  bucketName ,  testObject ,  uploadID ,  parts ,  ObjectOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Test: %s complete multipart upload failed: <ERROR> %v" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  result . Size  !=  int64 ( len ( bytesData [ 0 ] . byteData ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Test: %s expected size not written: expected %d, got %d" ,  instanceType ,  len ( bytesData [ 0 ] . byteData ) ,  result . Size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  buf  bytes . Buffer 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									r ,  err  :=  obj . GetObjectNInfo ( context . Background ( ) ,  bucketName ,  testObject ,  nil ,  nil ,  readLock ,  ObjectOptions { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "Test: %s reading completed file failed: <ERROR> %v" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  _ ,  err  =  io . Copy ( & buf ,  r ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Test %s: Failed to fetch the copied object: <ERROR> %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! bytes . Equal ( buf . Bytes ( ) ,  bytesData [ 0 ] . byteData )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Test: %s returned data is not expected corruption detected:" ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling Copy Object Part API handler tests for both Erasure multiple disks and single node setup.
  
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPICopyObjectPartHandler ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecExtendedObjectLayerAPITest ( t ,  testAPICopyObjectPartHandler ,  [ ] string { "CopyObjectPart" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPICopyObjectPartHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectName  :=  "test-object" 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 00:42:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									opts  :=  ObjectOptions { } 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// set of byte data for PutObject.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// object has to be created before running tests for Copy Object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// this is required even to assert the copied object,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bytesData  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byteData  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ generateBytesData ( 6  *  humanize . KiByte ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set of inputs for uploading the objects before tests for downloading is done.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									putObjectInputs  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										contentLength  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										textData       [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metaData       map [ string ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  int64 ( len ( bytesData [ 0 ] . byteData ) ) ,  bytesData [ 0 ] . byteData ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// iterate through the above set of inputs and upload the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  input  :=  range  putObjectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// uploading the object.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-27 14:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  obj . PutObject ( context . Background ( ) ,  input . bucketName ,  input . objectName ,  mustGetPutObjReader ( t ,  bytes . NewReader ( input . textData ) ,  input . contentLength ,  input . metaData [ "" ] ,  "" ) ,  ObjectOptions { UserDefined :  input . metaData } ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// if object upload fails stop the test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Put Object case %d:  Error uploading object: <ERROR> %v" ,  i + 1 ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Initiate Multipart upload for testing PutObjectPartHandler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testObject  :=  "testobject" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// PutObjectPart API HTTP Handler has to be tested in isolation,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// that is without any other handler being registered,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// That's why NewMultipartUpload is initiated using ObjectLayer.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 13:31:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uploadID ,  err  :=  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  testObject ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s : <ERROR>  %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// test cases with inputs and expected result for Copy Object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-20 04:53:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bucketName         string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										copySourceHeader   string  // data for "X-Amz-Copy-Source" header. Contains the object to be copied in the URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										copySourceRange    string  // data for "X-Amz-Copy-Source-Range" header, contains the byte range offsets of data to be copied.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uploadID           string  // uploadID of the transaction.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										invalidPartNumber  bool    // Sets an invalid multipart.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										maximumPartNumber  bool    // Sets a maximum parts.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accessKey          string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										secretKey          string 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// expected output.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedRespStatus  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 1, copy part 1 from from newObject1, ignore request headers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :            uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with invalid source object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with new object name is same as object to be copied.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Fail with file not found.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  testObject ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with valid byte range.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceRange :   "bytes=500-4096" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 5.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with invalid byte range.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceRange :   "bytes=6145-" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 6.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case with ivalid byte range for exceeding source size boundaries.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceRange :   "bytes=0-6144" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 7.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case with object name missing from source.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// fail with BadRequest.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "//123" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 8.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case with non-existent source file.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case for the purpose of failing `api.ObjectAPI.GetObjectInfo`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Expecting the response status code to http.StatusNotFound (404).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  "non-existent-object" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 9.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case with non-existent source file.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case for the purpose of failing `api.ObjectAPI.PutObjectPart`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Expecting the response status code to http.StatusNotFound (404).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        "non-existent-destination-bucket" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 10.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Case with invalid AccessKey.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         "Invalid-AccessID" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 11.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Case with non-existent upload id.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          "-1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 12.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// invalid part number.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :            uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											invalidPartNumber :   true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 13.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// maximum part number.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :            uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											maximumPartNumber :   true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 05:10:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 14, copy part 1 from from newObject1 with null versionId
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :            uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( SlashSeparator + bucketName + SlashSeparator + objectName )  +  "?versionId=null" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 05:10:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 15, copy part 1 from from newObject1 with non null versionId
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :            uploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( SlashSeparator + bucketName + SlashSeparator + objectName )  +  "?versionId=17" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 05:10:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 13:15:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 05:10:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 08:58:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 16,  Test case with ivalid byte range empty value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceRange :   "empty" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  testCase  :=  range  testCases  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  req  * http . Request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! testCase . invalidPartNumber  ||  ! testCase . maximumPartNumber  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// construct HTTP request for copy object.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req ,  err  =  newTestSignedRequestV4 ( http . MethodPut ,  getCopyObjectPartURL ( "" ,  testCase . bucketName ,  testObject ,  testCase . uploadID ,  "1" ) ,  0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  testCase . invalidPartNumber  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req ,  err  =  newTestSignedRequestV4 ( http . MethodPut ,  getCopyObjectPartURL ( "" ,  testCase . bucketName ,  testObject ,  testCase . uploadID ,  "abc" ) ,  0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  testCase . maximumPartNumber  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req ,  err  =  newTestSignedRequestV4 ( http . MethodPut ,  getCopyObjectPartURL ( "" ,  testCase . bucketName ,  testObject ,  testCase . uploadID ,  "99999" ) ,  0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: Failed to create HTTP request for copy Object: <ERROR> %v" ,  i + 1 ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// "X-Amz-Copy-Source" header contains the information about the source bucket and the object to copied.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . copySourceHeader  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( "X-Amz-Copy-Source" ,  testCase . copySourceHeader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . copySourceRange  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-04 08:58:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  testCase . copySourceRange  ==  "empty"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												req . Header . Set ( "X-Amz-Copy-Source-Range" ,  "" )  // specifically test for S3 errors in this scenario.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												req . Header . Set ( "X-Amz-Copy-Source-Range" ,  testCase . copySourceRange ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler, `func (api objectAPIHandlers) CopyObjectHandler` handles the request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s:  Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  ==  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// See if the new part has been uploaded.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// testing whether the copy was successful.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  results  ListPartsInfo 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-06 06:16:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											results ,  err  =  obj . ListObjectParts ( context . Background ( ) ,  testCase . bucketName ,  testObject ,  testCase . uploadID ,  0 ,  1 ,  ObjectOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Failed to look for copied object part: <ERROR> %s" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-31 01:58:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  len ( results . Parts )  !=  1  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Expected only one entry returned %d entries" ,  i + 1 ,  instanceType ,  len ( results . Parts ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// HTTP request for testing when `ObjectLayer` is set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There is no need to use an existing bucket and valid input for creating the request
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodPut ,  getCopyObjectPartURL ( "" ,  nilBucket ,  nilObject ,  "0" ,  "0" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  bytes . NewReader ( [ ] byte ( "testNilObjLayer" ) ) ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s: Failed to create http request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Below is how CopyObjectPartHandler is registered.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// bucket.Methods(http.MethodPut).Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(api.CopyObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}")
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Its necessary to set the "X-Amz-Copy-Source" header for the request to be accepted by the handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq . Header . Set ( "X-Amz-Copy-Source" ,  url . QueryEscape ( SlashSeparator + nilBucket + SlashSeparator + nilObject ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` manages the operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling Copy Object API handler tests for both Erasure multiple disks and single node setup.
  
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  TestAPICopyObjectHandler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecExtendedObjectLayerAPITest ( t ,  testAPICopyObjectHandler ,  [ ] string { "CopyObject" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  testAPICopyObjectHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2019-01-11 05:10:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectName  :=  "test?object"  // use file with ? to test URL parsing...
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  runtime . GOOS  ==  "windows"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName  =  "test-object"  // ...except on Windows
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// object used for anonymous HTTP request test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonObject  :=  "anon-object" 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 00:42:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									opts  :=  ObjectOptions { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// set of byte data for PutObject.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// object has to be created before running tests for Copy Object.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// this is required even to assert the copied object,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bytesData  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byteData  [ ] byte 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										md5sum    string 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ byteData :  generateBytesData ( 6  *  humanize . KiByte ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									h  :=  md5 . New ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									h . Write ( bytesData [ 0 ] . byteData ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bytesData [ 0 ] . md5sum  =  hex . EncodeToString ( h . Sum ( nil ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buffers  :=  [ ] * bytes . Buffer { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new ( bytes . Buffer ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new ( bytes . Buffer ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set of inputs for uploading the objects before tests for downloading is done.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									putObjectInputs  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										contentLength  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										textData       [ ] byte 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										md5sum         string 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										metaData       map [ string ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// case - 1.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  int64 ( len ( bytesData [ 0 ] . byteData ) ) ,  bytesData [ 0 ] . byteData ,  bytesData [ 0 ] . md5sum ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// used for anonymous HTTP request test.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ bucketName ,  anonObject ,  int64 ( len ( bytesData [ 0 ] . byteData ) ) ,  bytesData [ 0 ] . byteData ,  bytesData [ 0 ] . md5sum ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// iterate through the above set of inputs and upload the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  input  :=  range  putObjectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// uploading the object.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  objInfo  ObjectInfo 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-27 14:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										objInfo ,  err  =  obj . PutObject ( context . Background ( ) ,  input . bucketName ,  input . objectName ,  mustGetPutObjReader ( t ,  bytes . NewReader ( input . textData ) ,  input . contentLength ,  input . md5sum ,  "" ) ,  ObjectOptions { UserDefined :  input . metaData } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// if object upload fails stop the test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Put Object case %d:  Error uploading object: <ERROR> %v" ,  i + 1 ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  objInfo . ETag  !=  input . md5sum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Put Object case %d:  Checksum mismatched: <ERROR> got %s, expected %s" ,  i + 1 ,  input . md5sum ,  objInfo . ETag ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// test cases with inputs and expected result for Copy Object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bucketName            string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newObjectName         string  // name of the newly copied object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										copySourceHeader      string  // data for "X-Amz-Copy-Source" header. Contains the object to be copied in the URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										copyModifiedHeader    string  // data for "X-Amz-Copy-Source-If-Modified-Since" header
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										copyUnmodifiedHeader  string  // data for "X-Amz-Copy-Source-If-Unmodified-Since" header
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										copySourceSame        bool 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										metadataGarbage       bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metadataReplace       bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metadataCopy          bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metadata              map [ string ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accessKey             string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										secretKey             string 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// expected output.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedRespStatus  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusMethodNotAllowed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 1, copy metadata from newObject1, ignore request headers.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										1 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     "newObject1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											metadata :  map [ string ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"Content-Type" :  "application/json" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with invalid source object.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										2 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     "newObject1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// Test case - 3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with new object name is same as object to be copied.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										3 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceSame :    true , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// Test case - 4.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-30 00:21:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case with new object name is same as object to be copied.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// But source copy is without leading slash
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										4 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-30 00:21:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceSame :    true , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-30 00:21:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 5.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case with new object name is same as object to be copied
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// but metadata is updated.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										5 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											metadata :  map [ string ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"Content-Type" :  "application/json" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											metadataReplace :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :        credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :        credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-30 00:21:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 6.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case with invalid metadata-directive.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										6 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     "newObject1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											metadata :  map [ string ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"Content-Type" :  "application/json" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											metadataGarbage :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :        credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :        credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-30 00:21:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 7.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case with new object name is same as object to be copied
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// fail with BadRequest.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										7 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											metadata :  map [ string ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"Content-Type" :  "application/json" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceSame :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											metadataCopy :    true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :       credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :       credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-30 00:21:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 8.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// Test case with non-existent source file.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case for the purpose of failing `api.ObjectAPI.GetObjectInfo`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Expecting the response status code to http.StatusNotFound (404).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										8 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  "non-existent-object" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-30 00:21:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 9.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// Test case with non-existent source file.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case for the purpose of failing `api.ObjectAPI.PutObject`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Expecting the response status code to http.StatusNotFound (404).
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										9 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        "non-existent-destination-bucket" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-30 00:21:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 10.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Case with invalid AccessKey.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										10 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :         "Invalid-AccessID" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 11, copy metadata from newObject1 with satisfying modified header.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										11 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :       "newObject1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copyModifiedHeader :  "Mon, 02 Jan 2006 15:04:05 GMT" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 12, copy metadata from newObject1 with unsatisfying modified header.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										12 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :       "newObject1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copyModifiedHeader :  "Mon, 02 Jan 2217 15:04:05 GMT" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusPreconditionFailed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 13, copy metadata from newObject1 with wrong modified header format
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										13 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :       "newObject1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copyModifiedHeader :  "Mon, 02 Jan 2217 15:04:05 +00:00" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 14, copy metadata from newObject1 with satisfying unmodified header.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										14 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :            bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :         "newObject1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :      url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copyUnmodifiedHeader :  "Mon, 02 Jan 2217 15:04:05 GMT" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :             credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :             credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :    http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 15, copy metadata from newObject1 with unsatisfying unmodified header.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										15 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :            bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :         "newObject1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :      url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copyUnmodifiedHeader :  "Mon, 02 Jan 2007 15:04:05 GMT" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :             credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :             credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :    http . StatusPreconditionFailed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 16, copy metadata from newObject1 with incorrect unmodified header format.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										16 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :            bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :         "newObject1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :      url . QueryEscape ( SlashSeparator  +  bucketName  +  SlashSeparator  +  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copyUnmodifiedHeader :  "Mon, 02 Jan 2007 15:04:05 +00:00" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :             credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :             credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :    http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 05:10:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 17, copy metadata from newObject1 with null versionId
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										17 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 05:10:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :       "newObject1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( SlashSeparator + bucketName + SlashSeparator + objectName )  +  "?versionId=null" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 05:10:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 18, copy metadata from newObject1 with non null versionId
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										18 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 05:10:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :       "newObject1" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( SlashSeparator + bucketName + SlashSeparator + objectName )  +  "?versionId=17" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 05:10:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-29 13:15:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-11 05:10:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  testCase  :=  range  testCases  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  req  * http . Request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  reqV2  * http . Request 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// construct HTTP request for copy object.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( http . MethodPut ,  getCopyObjectURL ( "" ,  testCase . bucketName ,  testCase . newObjectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: Failed to create HTTP request for copy Object: <ERROR> %v" ,  i ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// "X-Amz-Copy-Source" header contains the information about the source bucket and the object to copied.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . copySourceHeader  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( "X-Amz-Copy-Source" ,  testCase . copySourceHeader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  testCase . copyModifiedHeader  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( "X-Amz-Copy-Source-If-Modified-Since" ,  testCase . copyModifiedHeader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . copyUnmodifiedHeader  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( "X-Amz-Copy-Source-If-Unmodified-Since" ,  testCase . copyUnmodifiedHeader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Add custom metadata.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  k ,  v  :=  range  testCase . metadata  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( k ,  v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . metadataReplace  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( "X-Amz-Metadata-Directive" ,  "REPLACE" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . metadataCopy  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( "X-Amz-Metadata-Directive" ,  "COPY" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . metadataGarbage  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( "X-Amz-Metadata-Directive" ,  "Unknown" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler, `func (api objectAPIHandlers) CopyObjectHandler` handles the request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  testCase . copySourceSame  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// encryption will rotate creds, so fail only for non-encryption scenario.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  GlobalKMS  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													t . Errorf ( "Test %d: %s:  Expected the response status to be `%d`, but instead found `%d`" ,  i ,  instanceType ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "Test %d: %s:  Expected the response status to be `%d`, but instead found `%d`" ,  i ,  instanceType ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  ==  http . StatusOK  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  cpObjResp  CopyObjectResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  =  xml . Unmarshal ( rec . Body . Bytes ( ) ,  & cpObjResp ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Failed to parse the CopyObjectResult response: <ERROR> %s" ,  i ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-28 05:23:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											// See if the new object is formed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// testing whether the copy was successful.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Note that this goes directly to the file system,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// so encryption/compression may interfere at some point.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											buffers [ 0 ] . Reset ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r ,  err  :=  obj . GetObjectNInfo ( context . Background ( ) ,  testCase . bucketName ,  testCase . newObjectName ,  nil ,  nil ,  readLock ,  opts ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s reading completed file failed: <ERROR> %v" ,  i ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  err  =  io . Copy ( buffers [ 0 ] ,  r ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												r . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d %s: Failed to fetch the copied object: <ERROR> %s" ,  i ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! bytes . Equal ( bytesData [ 0 ] . byteData ,  buffers [ 0 ] . Bytes ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "Test %d: %s: Data Mismatch: Data fetched back from the copied object doesn't match the original one." ,  i ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Verify response of the V2 signed HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										recV2  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reqV2 ,  err  =  newTestRequest ( http . MethodPut ,  getCopyObjectURL ( "" ,  testCase . bucketName ,  testCase . newObjectName ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: Failed to create HTTP request for copy Object: <ERROR> %v" ,  i ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// "X-Amz-Copy-Source" header contains the information about the source bucket and the object to copied.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . copySourceHeader  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . Header . Set ( "X-Amz-Copy-Source" ,  testCase . copySourceHeader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-13 03:34:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  testCase . copyModifiedHeader  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . Header . Set ( "X-Amz-Copy-Source-If-Modified-Since" ,  testCase . copyModifiedHeader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . copyUnmodifiedHeader  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . Header . Set ( "X-Amz-Copy-Source-If-Unmodified-Since" ,  testCase . copyUnmodifiedHeader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Add custom metadata.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  k ,  v  :=  range  testCase . metadata  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . Header . Set ( k ,  v + "+x" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . metadataReplace  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . Header . Set ( "X-Amz-Metadata-Directive" ,  "REPLACE" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . metadataCopy  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . Header . Set ( "X-Amz-Metadata-Directive" ,  "COPY" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . metadataGarbage  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . Header . Set ( "X-Amz-Metadata-Directive" ,  "Unknown" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  signRequestV2 ( reqV2 ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Failed to V2 Sign the HTTP request: %v." ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( recV2 ,  reqV2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  recV2 . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-23 04:09:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  testCase . copySourceSame  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// encryption will rotate creds, so fail only for non-encryption scenario.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  GlobalKMS  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													t . Errorf ( "Test %d: %s:  Expected the response status to be `%d`, but instead found `%d`" ,  i ,  instanceType ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "Test %d: %s:  Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// HTTP request to test the case of `objectLayer` being set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There is no need to use an existing bucket or valid input for creating the request,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodPut ,  getCopyObjectURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Below is how CopyObjectHandler is registered.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// bucket.Methods(http.MethodPut).Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?")
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Its necessary to set the "X-Amz-Copy-Source" header for the request to be accepted by the handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq . Header . Set ( "X-Amz-Copy-Source" ,  url . QueryEscape ( SlashSeparator + nilBucket + SlashSeparator + nilObject ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` manages the operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling NewMultipartUpload tests for both Erasure multiple disks and single node setup.
  
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// First register the HTTP handler for NewMutlipartUpload, then a HTTP request for NewMultipart upload is made.
  
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The UploadID from the response body is parsed and its existence is asserted with an attempt to ListParts using it.
  
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPINewMultipartHandler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPINewMultipartHandler ,  [ ] string { "NewMultipart" } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPINewMultipartHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectName  :=  "test-object-new-multipart" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// construct HTTP request for NewMultipart upload.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req ,  err  :=  newTestSignedRequestV4 ( http . MethodPost ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "Failed to create HTTP request for NewMultipart Request: <ERROR> %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Call the ServeHTTP to executes the registered handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rec . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s:  Expected the response status to be `%d`, but instead found `%d`" ,  instanceType ,  http . StatusOK ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// decode the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									decoder  :=  xml . NewDecoder ( rec . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									multipartResponse  :=  & InitiateMultipartUploadResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  decoder . Decode ( multipartResponse ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Error decoding the recorded response Body" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// verify the uploadID my making an attempt to list parts.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-06 06:16:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  =  obj . ListObjectParts ( context . Background ( ) ,  bucketName ,  objectName ,  multipartResponse . UploadID ,  0 ,  1 ,  ObjectOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Invalid UploadID: <ERROR> %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Testing the response for Invalid AcccessID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Forcing the signature check to fail.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// construct HTTP request for NewMultipart upload.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Setting an invalid accessID.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req ,  err  =  newTestSignedRequestV4 ( http . MethodPost ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "Invalid-AccessID" ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Failed to create HTTP request for NewMultipart Request: <ERROR> %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP method to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Call the ServeHTTP to executes the registered handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rec . Code  !=  http . StatusForbidden  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s:  Expected the response status to be `%d`, but instead found `%d`" ,  instanceType ,  http . StatusForbidden ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Verify response of the V2 signed HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									recV2  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// construct HTTP request for NewMultipartUpload endpoint.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reqV2 ,  err  :=  newTestSignedRequestV2 ( http . MethodPost ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Failed to create HTTP request for NewMultipart Request: <ERROR> %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Call the ServeHTTP to execute the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( recV2 ,  reqV2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  recV2 . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s:  Expected the response status to be `%d`, but instead found `%d`" ,  instanceType ,  http . StatusOK ,  recV2 . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// decode the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									decoder  =  xml . NewDecoder ( recV2 . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									multipartResponse  =  & InitiateMultipartUploadResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  decoder . Decode ( multipartResponse ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Error decoding the recorded response Body" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// verify the uploadID my making an attempt to list parts.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-06 06:16:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  =  obj . ListObjectParts ( context . Background ( ) ,  bucketName ,  objectName ,  multipartResponse . UploadID ,  0 ,  1 ,  ObjectOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Invalid UploadID: <ERROR> %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Testing the response for invalid AcccessID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Forcing the V2 signature check to fail.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									recV2  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// construct HTTP request for NewMultipartUpload endpoint.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Setting invalid AccessID.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reqV2 ,  err  =  newTestSignedRequestV2 ( http . MethodPost ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "Invalid-AccessID" ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Failed to create HTTP request for NewMultipart Request: <ERROR> %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Call the ServeHTTP to execute the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( recV2 ,  reqV2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  recV2 . Code  !=  http . StatusForbidden  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s:  Expected the response status to be `%d`, but instead found `%d`" ,  instanceType ,  http . StatusForbidden ,  recV2 . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Test for Anonymous/unsigned http request.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( http . MethodPost ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s: Failed to create an anonymous request for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  objectName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// unsigned request goes through and its validated again.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPIAnonTest ( t ,  obj ,  "TestAPINewMultipartHandler" ,  bucketName ,  objectName ,  instanceType ,  apiRouter ,  anonReq ,  getAnonWriteOnlyObjectPolicy ( bucketName ,  objectName ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HTTP request to test the case of `objectLayer` being set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There is no need to use an existing bucket or valid input for creating the request,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodPost ,  getNewMultipartURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` manages the operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling NewMultipartUploadParallel tests for both Erasure multiple disks and single node setup.
  
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The objective of the test is to initialte multipart upload on the same object 10 times concurrently,
  
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The UploadID from the response body is parsed and its existence is asserted with an attempt to ListParts using it.
  
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPINewMultipartHandlerParallel ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPINewMultipartHandlerParallel ,  [ ] string { "NewMultipart" } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPINewMultipartHandlerParallel ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-04-14 03:00:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// used for storing the uploadID's parsed on concurrent HTTP requests for NewMultipart upload on the same object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testUploads  :=  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sync . Mutex 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uploads  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectName  :=  "test-object-new-multipart-parallel" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  wg  sync . WaitGroup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <  10 ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wg . Add ( 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Initiate NewMultipart upload on the same object 10 times concurrrently.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										go  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defer  wg . Done ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// construct HTTP request NewMultipartUpload.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req ,  err  :=  newTestSignedRequestV4 ( http . MethodPost ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) ,  0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-24 00:44:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t . Errorf ( "Failed to create HTTP request for NewMultipart request: <ERROR> %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Call the ServeHTTP to executes the registered handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  rec . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t . Errorf ( "MinIO %s:  Expected the response status to be `%d`, but instead found `%d`" ,  instanceType ,  http . StatusOK ,  rec . Code ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-24 00:44:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// decode the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											decoder  :=  xml . NewDecoder ( rec . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											multipartResponse  :=  & InitiateMultipartUploadResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  decoder . Decode ( multipartResponse ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t . Errorf ( "MinIO %s: Error decoding the recorded response Body" ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-24 00:44:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// push the obtained upload ID from the response into the array.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											testUploads . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											testUploads . uploads  =  append ( testUploads . uploads ,  multipartResponse . UploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											testUploads . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Wait till all go routines finishes execution.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wg . Wait ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Validate the upload ID by an attempt to list parts using it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  uploadID  :=  range  testUploads . uploads  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-06 06:16:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  :=  obj . ListObjectParts ( context . Background ( ) ,  bucketName ,  objectName ,  uploadID ,  0 ,  1 ,  ObjectOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Invalid UploadID: <ERROR> %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The UploadID from the response body is parsed and its existence is asserted with an attempt to ListParts using it.
  
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPICompleteMultipartHandler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPICompleteMultipartHandler ,  [ ] string { "CompleteMultipart" } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPICompleteMultipartHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 00:42:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  opts  ObjectOptions 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// object used for the test.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectName  :=  "test-object-new-multipart" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// uploadID obtained from NewMultipart upload.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  uploadID  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// upload IDs collected.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  uploadIDs  [ ] string 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <  2 ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initiate new multipart uploadID.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 13:31:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										uploadID ,  err  =  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  objectName ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "MinIO %s : <ERROR>  %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uploadIDs  =  append ( uploadIDs ,  uploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-05 23:28:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Parts with size greater than 5 MiB.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Generating a 6 MiB byte array.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									validPart  :=  bytes . Repeat ( [ ] byte ( "abcdef" ) ,  1 * humanize . MiByte ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-22 05:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									validPartMD5  :=  getMD5Hash ( validPart ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Create multipart parts.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Need parts to be uploaded before CompleteMultiPartUpload can be called tested.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parts  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName       string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objName          string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uploadID         string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PartID           int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										inputReaderData  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										inputMd5         string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										intputDataSize   int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case 1-4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Creating sequence of parts for same uploadID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  1 ,  "abcd" ,  "e2fc714c4727ee9395f324cd2e7f331f" ,  int64 ( len ( "abcd" ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  2 ,  "efgh" ,  "1f7690ebdd9b4caf8fab49ca1757bf27" ,  int64 ( len ( "efgh" ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  3 ,  "ijkl" ,  "09a0877d04abf8759f99adec02baf579" ,  int64 ( len ( "abcd" ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  4 ,  "mnop" ,  "e132e96a5ddad6da8b07bba6f6131fef" ,  int64 ( len ( "abcd" ) ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-05 23:28:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Part with size larger than 5 MiB.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  5 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( validPart ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  6 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( validPart ) ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-05 23:28:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Part with size larger than 5 MiB.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Parts uploaded for anonymous/unsigned API handler test.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 1 ] ,  1 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( validPart ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 1 ] ,  2 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( validPart ) ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Iterating over creatPartCases to generate multipart chunks.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  part  :=  range  parts  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  obj . PutObjectPart ( context . Background ( ) ,  part . bucketName ,  part . objName ,  part . uploadID ,  part . PartID , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-27 14:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											mustGetPutObjReader ( t ,  strings . NewReader ( part . inputReaderData ) ,  part . intputDataSize ,  part . inputMd5 ,  "" ) ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "%s : %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Parts to be sent as input for CompleteMultipartUpload.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									inputParts  :=  [ ] struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										parts  [ ] CompletePart 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// inputParts - 0.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case for replicating ETag mismatch.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											[ ] CompletePart { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												{ ETag :  "abcd" ,  PartNumber :  1 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// inputParts - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// should error out with part too small.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											[ ] CompletePart { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												{ ETag :  "e2fc714c4727ee9395f324cd2e7f331f" ,  PartNumber :  1 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ ETag :  "1f7690ebdd9b4caf8fab49ca1757bf27" ,  PartNumber :  2 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// inputParts - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with invalid Part number.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											[ ] CompletePart { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												{ ETag :  "e2fc714c4727ee9395f324cd2e7f331f" ,  PartNumber :  10 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// inputParts - 3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with valid parts,but parts are unsorted.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-05 23:28:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Part size greater than 5 MiB.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											[ ] CompletePart { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												{ ETag :  validPartMD5 ,  PartNumber :  6 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ ETag :  validPartMD5 ,  PartNumber :  5 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// inputParts - 4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with valid part.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-05 23:28:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Part size greater than 5 MiB.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											[ ] CompletePart { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												{ ETag :  validPartMD5 ,  PartNumber :  5 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ ETag :  validPartMD5 ,  PartNumber :  6 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// inputParts - 5.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Used for the case of testing for anonymous API request.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-05 23:28:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Part size greater than 5 MiB.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											[ ] CompletePart { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												{ ETag :  validPartMD5 ,  PartNumber :  1 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ ETag :  validPartMD5 ,  PartNumber :  2 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 23:46:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// on successful complete multipart operation the s3MD5 for the parts uploaded will be returned.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-09 09:35:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s3MD5  :=  getCompleteMultipartMD5 ( inputParts [ 3 ] . parts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// generating the response body content for the success case.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									successResponse  :=  generateCompleteMultpartUploadResponse ( bucketName ,  objectName ,  getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  s3MD5 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									encodedSuccessResponse  :=  encodeResponse ( successResponse ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 03:07:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  context . Background ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bucket     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										object     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uploadID   string 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										parts      [ ] CompletePart 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accessKey  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										secretKey  string 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Expected output of CompleteMultipartUpload.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedContent  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Expected HTTP Response status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedRespStatus  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Upload and PartNumber exists, But a deliberate ETag mismatch is introduced.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket :     bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :   uploadIDs [ 0 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parts :      inputParts [ 0 ] . parts , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :  credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :  credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												toAPIError ( ctx ,  InvalidPart { } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 2.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// No parts specified in CompletePart{}.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Should return ErrMalformedXML in the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket :     bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :   uploadIDs [ 0 ] , 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											parts :      [ ] CompletePart { } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :  credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :  credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getAPIError ( ErrMalformedXML ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 3.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Non-Existent uploadID.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// 404 Not Found response status expected.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket :     bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :   "abc" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parts :      inputParts [ 0 ] . parts , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :  credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :  credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												toAPIError ( ctx ,  InvalidUploadID { UploadID :  "abc" } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with part size being less than minimum allowed size.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket :     bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :   uploadIDs [ 0 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parts :      inputParts [ 1 ] . parts , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :  credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :  credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-21 14:20:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												toAPIError ( ctx ,  PartTooSmall { PartNumber :  1 } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 5.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// TestCase with invalid Part Number.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket :     bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :   uploadIDs [ 0 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parts :      inputParts [ 2 ] . parts , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :  credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :  credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												toAPIError ( ctx ,  InvalidPart { } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 6.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Parts are not sorted according to the part number.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This should return ErrInvalidPartOrder in the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket :     bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :   uploadIDs [ 0 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parts :      inputParts [ 3 ] . parts , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :  credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :  credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getAPIError ( ErrInvalidPartOrder ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 7.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with proper parts.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Should successed and the content in the response body is asserted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket :     bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :   uploadIDs [ 0 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parts :      inputParts [ 4 ] . parts , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :  "Invalid-AccessID" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											secretKey :  credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( ctx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getAPIError ( ErrInvalidAccessKeyID ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  "" ,  "" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 8.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with proper parts.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Should successed and the content in the response body is asserted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket :     bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :   uploadIDs [ 0 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parts :      inputParts [ 4 ] . parts , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :  credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :  credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :     encodedSuccessResponse , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  testCase  :=  range  testCases  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  req  * http . Request 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  completeBytes ,  actualContent  [ ] byte 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Complete multipart upload parts.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										completeUploads  :=  & CompleteMultipartUpload { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Parts :  testCase . parts , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										completeBytes ,  err  =  xml . Marshal ( completeUploads ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Error XML encoding of parts: <ERROR> %s." ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Indicating that all parts are uploaded and initiating CompleteMultipartUpload.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( http . MethodPost ,  getCompleteMultipartUploadURL ( "" ,  bucketName ,  objectName ,  testCase . uploadID ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int64 ( len ( completeBytes ) ) ,  bytes . NewReader ( completeBytes ) ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "Failed to create HTTP request for CompleteMultipartUpload: <ERROR> %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to executes the registered handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "Case %d: MinIO %s: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// read the response body.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										actualContent ,  err  =  ioutil . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d : MinIO %s: Failed parsing response body: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  ==  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Verify whether the bucket obtained object is same as the one created.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! bytes . Equal ( testCase . expectedContent ,  actualContent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-02 11:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t . Errorf ( "Test %d : MinIO %s: CompleteMultipart response content differs from expected value. got %s, expecte %s" ,  i + 1 ,  instanceType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													string ( actualContent ) ,  string ( testCase . expectedContent ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										actualError  :=  & APIErrorResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  xml . Unmarshal ( actualContent ,  actualError ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "MinIO %s: error response failed to parse error XML" ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actualError . BucketName  !=  bucketName  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "MinIO %s: error response bucket name differs from expected value" ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  actualError . Key  !=  objectName  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-10 04:58:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "MinIO %s: error response object name (%s) differs from expected value (%s)" ,  instanceType ,  actualError . Key ,  objectName ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Testing for anonymous API request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  completeBytes  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Complete multipart upload parts.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									completeUploads  :=  & CompleteMultipartUpload { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Parts :  inputParts [ 5 ] . parts , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									completeBytes ,  err  =  xml . Marshal ( completeUploads ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Error XML encoding of parts: <ERROR> %s." ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create unsigned HTTP request for CompleteMultipart upload.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( http . MethodPost ,  getCompleteMultipartUploadURL ( "" ,  bucketName ,  objectName ,  uploadIDs [ 1 ] ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int64 ( len ( completeBytes ) ) ,  bytes . NewReader ( completeBytes ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s: Failed to create an anonymous request for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  objectName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// unsigned request goes through and its validated again.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-10 07:19:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPIAnonTest ( t ,  obj ,  "TestAPICompleteMultipartHandler" ,  bucketName ,  objectName ,  instanceType , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiRouter ,  anonReq ,  getAnonWriteOnlyObjectPolicy ( bucketName ,  objectName ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HTTP request to test the case of `objectLayer` being set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There is no need to use an existing bucket or valid input for creating the request,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-14 16:25:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Indicating that all parts are uploaded and initiating CompleteMultipartUpload.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodPost ,  getCompleteMultipartUploadURL ( "" ,  nilBucket ,  nilObject ,  "dummy-uploadID" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` manages the operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The UploadID from the response body is parsed and its existence is asserted with an attempt to ListParts using it.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPIAbortMultipartHandler ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPIAbortMultipartHandler ,  [ ] string { "AbortMultipart" } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPIAbortMultipartHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 00:42:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									opts  :=  ObjectOptions { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// object used for the test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectName  :=  "test-object-new-multipart" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// uploadID obtained from NewMultipart upload.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  uploadID  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// upload IDs collected.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  uploadIDs  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <  2 ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initiate new multipart uploadID.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 13:31:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										uploadID ,  err  =  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  objectName ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "MinIO %s : <ERROR>  %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uploadIDs  =  append ( uploadIDs ,  uploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-05 23:28:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Parts with size greater than 5 MiB.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Generating a 6 MiB byte array.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									validPart  :=  bytes . Repeat ( [ ] byte ( "abcdef" ) ,  1 * humanize . MiByte ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-22 05:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									validPartMD5  :=  getMD5Hash ( validPart ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Create multipart parts.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Need parts to be uploaded before AbortMultiPartUpload can be called tested.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parts  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName       string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objName          string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uploadID         string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PartID           int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										inputReaderData  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										inputMd5         string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										intputDataSize   int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case 1-4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Creating sequence of parts for same uploadID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  1 ,  "abcd" ,  "e2fc714c4727ee9395f324cd2e7f331f" ,  int64 ( len ( "abcd" ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  2 ,  "efgh" ,  "1f7690ebdd9b4caf8fab49ca1757bf27" ,  int64 ( len ( "efgh" ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  3 ,  "ijkl" ,  "09a0877d04abf8759f99adec02baf579" ,  int64 ( len ( "abcd" ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  4 ,  "mnop" ,  "e132e96a5ddad6da8b07bba6f6131fef" ,  int64 ( len ( "abcd" ) ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-05 23:28:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Part with size larger than 5 MiB.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  5 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( validPart ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  6 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( validPart ) ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-05 23:28:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Part with size larger than 5 MiB.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Parts uploaded for anonymous/unsigned API handler test.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 1 ] ,  1 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( validPart ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 1 ] ,  2 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( validPart ) ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Iterating over createPartCases to generate multipart chunks.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  part  :=  range  parts  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  obj . PutObjectPart ( context . Background ( ) ,  part . bucketName ,  part . objName ,  part . uploadID ,  part . PartID , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-27 14:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											mustGetPutObjReader ( t ,  strings . NewReader ( part . inputReaderData ) ,  part . intputDataSize ,  part . inputMd5 ,  "" ) ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "%s : %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucket     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										object     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uploadID   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accessKey  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										secretKey  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Expected HTTP Response status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedRespStatus  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Abort existing upload ID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket :              bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object :              objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :            uploadIDs [ 0 ] , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNoContent , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Abort non-existng upload ID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket :              bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object :              objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :            "nonexistent-upload-id" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Abort with unknown Access key.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket :              bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object :              objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :            uploadIDs [ 0 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           "Invalid-AccessID" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  testCase  :=  range  testCases  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  req  * http . Request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Indicating that all parts are uploaded and initiating abortMultipartUpload.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( http . MethodDelete ,  getAbortMultipartUploadURL ( "" ,  testCase . bucket ,  testCase . object ,  testCase . uploadID ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Failed to create HTTP request for AbortMultipartUpload: <ERROR> %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to executes the registered handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "Case %d: MinIO %s: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create unsigned HTTP request for Abort multipart upload.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( http . MethodDelete ,  getAbortMultipartUploadURL ( "" ,  bucketName ,  objectName ,  uploadIDs [ 1 ] ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s: Failed to create an anonymous request for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  objectName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// unsigned request goes through and its validated again.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-10 07:19:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPIAnonTest ( t ,  obj ,  "TestAPIAbortMultipartHandler" ,  bucketName ,  objectName ,  instanceType , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiRouter ,  anonReq ,  getAnonWriteOnlyObjectPolicy ( bucketName ,  objectName ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// HTTP request to test the case of `objectLayer` being set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There is no need to use an existing bucket or valid input for creating the request,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Indicating that all parts are uploaded and initiating abortMultipartUpload.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodDelete ,  getAbortMultipartUploadURL ( "" ,  nilBucket ,  nilObject ,  "dummy-uploadID" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` manages the operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling Delete Object API handler tests for both Erasure multiple disks and FS single drive setup.
  
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPIDeleteObjectHandler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPIDeleteObjectHandler ,  [ ] string { "DeleteObject" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  testAPIDeleteObjectHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectName  :=  "test-object" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Object used for anonymous API request test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonObjectName  :=  "test-anon-obj" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// set of byte data for PutObject.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// object has to be created before running tests for Deleting the object.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bytesData  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										byteData  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ generateBytesData ( 6  *  humanize . MiByte ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set of inputs for uploading the objects before tests for deleting them is done.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									putObjectInputs  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										contentLength  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										textData       [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										metaData       map [ string ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  int64 ( len ( bytesData [ 0 ] . byteData ) ) ,  bytesData [ 0 ] . byteData ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  anonObjectName ,  int64 ( len ( bytesData [ 0 ] . byteData ) ) ,  bytesData [ 0 ] . byteData ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// iterate through the above set of inputs and upload the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  input  :=  range  putObjectInputs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// uploading the object.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-27 14:58:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  obj . PutObject ( context . Background ( ) ,  input . bucketName ,  input . objectName ,  mustGetPutObjReader ( t ,  bytes . NewReader ( input . textData ) ,  input . contentLength ,  input . metaData [ "" ] ,  "" ) ,  ObjectOptions { UserDefined :  input . metaData } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// if object upload fails stop the test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Put Object case %d:  Error uploading object: <ERROR> %v" ,  i + 1 ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// test cases with inputs and expected result for DeleteObject.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectName  string 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										accessKey   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										secretKey   string 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedRespStatus  int  // expected response status body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Deleting an existing object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Expected to return HTTP resposne status code 204.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNoContent , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Attempt to delete an object which is already deleted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Still should return http response status 204.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNoContent , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Setting Invalid AccessKey to force signature check inside the handler to fail.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Should return HTTP response status 403 forbidden.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :   "Invalid-AccessKey" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Iterating over the cases, call DeleteObjectHandler and validate the HTTP response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  testCase  :=  range  testCases  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  req ,  reqV2  * http . Request 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// construct HTTP request for Delete Object end point.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( http . MethodDelete ,  getDeleteObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: Failed to create HTTP request for Delete Object: <ERROR> %v" ,  i + 1 ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler,`func (api objectAPIHandlers) DeleteObjectHandler`  handles the request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rec . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "MinIO %s: Case %d: Expected the response status to be `%d`, but instead found `%d`" ,  instanceType ,  i + 1 ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Verify response of the V2 signed HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										recV2  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// construct HTTP request for Delete Object endpoint.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reqV2 ,  err  =  newTestSignedRequestV2 ( http . MethodDelete ,  getDeleteObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Failed to create HTTP request for NewMultipart Request: <ERROR> %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call the ServeHTTP to execute the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( recV2 ,  reqV2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Assert the response code with the expected status.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  recV2 . Code  !=  testCase . expectedRespStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "Case %d: MinIO %s: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												instanceType ,  testCase . expectedRespStatus ,  recV2 . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Test for Anonymous/unsigned http request.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( http . MethodDelete ,  getDeleteObjectURL ( "" ,  bucketName ,  anonObjectName ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s: Failed to create an anonymous request for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  anonObjectName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// unsigned request goes through and its validated again.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPIAnonTest ( t ,  obj ,  "TestAPIDeleteObjectHandler" ,  bucketName ,  anonObjectName ,  instanceType ,  apiRouter ,  anonReq ,  getAnonWriteOnlyObjectPolicy ( bucketName ,  anonObjectName ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HTTP request to test the case of `objectLayer` being set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There is no need to use an existing bucket or valid input for creating the request,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodDelete ,  getDeleteObjectURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` manages the operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TestAPIPutObjectPartHandlerStreaming - Tests validate the response of PutObjectPart HTTP handler
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// when the request signature type is `streaming signature`.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPIPutObjectPartHandlerStreaming ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecExtendedObjectLayerAPITest ( t ,  testAPIPutObjectPartHandlerStreaming ,  [ ] string { "NewMultipart" ,  "PutObjectPart" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPIPutObjectPartHandlerStreaming ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-04-14 03:00:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testObject  :=  "testobject" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req ,  err  :=  newTestSignedRequestV4 ( http . MethodPost ,  getNewMultipartURL ( "" ,  bucketName ,  "testobject" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] - Failed to create a signed request to initiate multipart upload for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get uploadID of the mulitpart upload initiated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  mpartResp  InitiateMultipartUploadResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mpartRespBytes ,  err  :=  ioutil . ReadAll ( rec . Result ( ) . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] Failed to read NewMultipartUpload response <ERROR> %v" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  xml . Unmarshal ( mpartRespBytes ,  & mpartResp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] Failed to unmarshal NewMultipartUpload response <ERROR> %v" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									noAPIErr  :=  APIError { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									missingDateHeaderErr  :=  getAPIError ( ErrMissingDateHeader ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-10 05:37:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									internalErr  :=  getAPIError ( ErrBadRequest ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fault        Fault 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedErr  APIError 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ BadSignature ,  missingDateHeaderErr } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ None ,  noAPIErr } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ TooBigDecodedLength ,  internalErr } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  test  :=  range  testCases  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  =  newTestStreamingSignedRequest ( http . MethodPut , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											getPutObjectPartURL ( "" ,  bucketName ,  testObject ,  mpartResp . UploadID ,  "1" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											5 ,  1 ,  bytes . NewReader ( [ ] byte ( "hello" ) ) ,  credentials . AccessKey ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-31 14:32:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Failed to create new streaming signed HTTP request: <ERROR> %v." ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										switch  test . fault  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  BadSignature : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Reset date field in header to make streaming signature fail.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( "x-amz-date" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  TooBigDecodedLength : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Set decoded length to a large value out of int64 range to simulate parse failure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( "x-amz-decoded-content-length" ,  "9999999999999999999999" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  test . expectedErr  !=  noAPIErr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											errBytes ,  err  :=  ioutil . ReadAll ( rec . Result ( ) . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d %s Failed to read error response from upload part request %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													i + 1 ,  instanceType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  errXML  APIErrorResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  xml . Unmarshal ( errBytes ,  & errXML ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d %s Failed to unmarshal error response from upload part request %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													i + 1 ,  instanceType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  test . expectedErr . Code  !=  errXML . Code  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "Test %d %s expected to fail with error %s, but received %s" ,  i + 1 ,  instanceType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													test . expectedErr . Code ,  errXML . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  rec . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Errorf ( "Test %d %s expected to succeed, but failed with HTTP status code %d" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													i + 1 ,  instanceType ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TestAPIPutObjectPartHandler - Tests validate the response of PutObjectPart HTTP handler
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  for variety of inputs.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPIPutObjectPartHandler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecExtendedObjectLayerAPITest ( t ,  testAPIPutObjectPartHandler ,  [ ] string { "PutObjectPart" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPIPutObjectPartHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Initiate Multipart upload for testing PutObjectPartHandler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testObject  :=  "testobject" 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 00:42:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  opts  ObjectOptions 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// PutObjectPart API HTTP Handler has to be tested in isolation,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// that is without any other handler being registered,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// That's why NewMultipartUpload is initiated using ObjectLayer.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 13:31:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uploadID ,  err  :=  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  testObject ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s : <ERROR>  %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uploadIDCopy  :=  uploadID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error types for invalid inputs to PutObjectPartHandler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									noAPIErr  :=  APIError { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error when content length is missing in the HTTP request.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									missingContent  :=  getAPIError ( ErrMissingContentLength ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error when content length is too large.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									entityTooLarge  :=  getAPIError ( ErrEntityTooLarge ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error when the signature check fails.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									badSigning  :=  getAPIError ( ErrSignatureDoesNotMatch ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error MD5 sum mismatch occurs.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									badChecksum  :=  getAPIError ( ErrInvalidDigest ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error when the part number in the request is invalid.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									invalidPart  :=  getAPIError ( ErrInvalidPart ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error when maxPart is beyond the limit.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									invalidMaxParts  :=  getAPIError ( ErrInvalidMaxParts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error the when the uploadID is invalid.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									noSuchUploadID  :=  getAPIError ( ErrNoSuchUpload ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error when InvalidAccessID is set.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									invalidAccessID  :=  getAPIError ( ErrInvalidAccessKeyID ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// SignatureMismatch for various signing types
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										objectName  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reader      io . ReadSeeker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										partNumber  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fault       Fault 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										accessKey   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										secretKey   string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										expectedAPIError  APIError 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Success case.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objectName :  testObject , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reader :      bytes . NewReader ( [ ] byte ( "hello" ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumber :  "1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :       None , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedAPIError :  noAPIErr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case where part number is invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objectName :  testObject , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reader :      bytes . NewReader ( [ ] byte ( "hello" ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumber :  "9999999999999999999" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :       None , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedAPIError :  invalidPart , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case where the part number has exceeded the max allowed parts in an upload.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objectName :  testObject , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reader :      bytes . NewReader ( [ ] byte ( "hello" ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 02:14:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											partNumber :  strconv . Itoa ( globalMaxPartID  +  1 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											fault :       None , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedAPIError :  invalidMaxParts , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case where the content length is not set in the HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objectName :  testObject , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reader :      bytes . NewReader ( [ ] byte ( "hello" ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumber :  "1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :       MissingContentLength , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedAPIError :  missingContent , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 5.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// case where the object size is set to a value greater than the max allowed size.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objectName :  testObject , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reader :      bytes . NewReader ( [ ] byte ( "hello" ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumber :  "1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :       TooBigObject , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedAPIError :  entityTooLarge , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 6.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// case where a signature mismatch is introduced and the response is validated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objectName :  testObject , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reader :      bytes . NewReader ( [ ] byte ( "hello" ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumber :  "1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :       BadSignature , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedAPIError :  badSigning , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 7.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case where incorrect checksum is set and the error response
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// is asserted with the expected error response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objectName :  testObject , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reader :      bytes . NewReader ( [ ] byte ( "hello" ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumber :  "1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :       BadMD5 , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedAPIError :  badChecksum , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 8.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// case where the a non-existent uploadID is set.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objectName :  testObject , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reader :      bytes . NewReader ( [ ] byte ( "hello" ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumber :  "1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :       MissingUploadID , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedAPIError :  noSuchUploadID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 9.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// case with invalid AccessID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Forcing the signature check inside the handler to fail.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  testObject , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reader :      bytes . NewReader ( [ ] byte ( "hello" ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumber :  "1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :       None , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :   "Invalid-AccessID" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedAPIError :  invalidAccessID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reqV2Str  :=  "V2 Signed HTTP request" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reqV4Str  :=  "V4 Signed HTTP request" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// collection of input HTTP request, ResponseRecorder and request type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Used to make a collection of V4 and V4 HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  inputReqRec  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req      * http . Request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec      * httptest . ResponseRecorder 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reqType  string 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  test  :=  range  testCases  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Using sub-tests introduced in Go 1.7.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Run ( fmt . Sprintf ( "MinIO %s : Test case %d." ,  instanceType ,  i + 1 ) ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  reqV4 ,  reqV2  * http . Request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  recV4 ,  recV2  * httptest . ResponseRecorder 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											recV4  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											recV2  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// setting a non-existent uploadID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// deliberately introducing the invalid value to be able to assert the response with the expected error response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  test . fault  ==  MissingUploadID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												uploadID  =  "upload1" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// constructing a v4 signed HTTP request.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reqV4 ,  err  =  newTestSignedRequestV4 ( http . MethodPut , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getPutObjectPartURL ( "" ,  bucketName ,  test . objectName ,  uploadID ,  test . partNumber ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												0 ,  test . reader ,  test . accessKey ,  test . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t . Fatalf ( "Failed to create a signed V4 request to upload part for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													bucketName ,  test . objectName ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Verify response of the V2 signed HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// construct HTTP request for PutObject Part Object endpoint.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reqV2 ,  err  =  newTestSignedRequestV2 ( http . MethodPut , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getPutObjectPartURL ( "" ,  bucketName ,  test . objectName ,  uploadID ,  test . partNumber ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												0 ,  test . reader ,  test . accessKey ,  test . secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d %s Failed to create a V2  signed request to upload part for %s/%s: <ERROR> %v" ,  i + 1 ,  instanceType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bucketName ,  test . objectName ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// collection of input HTTP request, ResponseRecorder and request type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqRecs  :=  [ ] inputReqRec { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													req :      reqV4 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rec :      recV4 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													reqType :  reqV4Str , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													req :      reqV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rec :      recV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													reqType :  reqV2Str , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											for  _ ,  reqRec  :=  range  reqRecs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Response recorder to record the response of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rec  :=  reqRec . rec 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// HTTP request used to call the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												req  :=  reqRec . req 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// HTTP request type string for V4/V2 requests.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reqType  :=  reqRec . reqType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// introduce faults in the request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// deliberately introducing the invalid value to be able to assert the response with the expected error response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												switch  test . fault  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  MissingContentLength : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													req . ContentLength  =  - 1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// Setting the content length to a value greater than the max allowed size of a part.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// Used in test case  4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  TooBigObject : 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 02:14:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													req . ContentLength  =  globalMaxObjectSize  +  1 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													// Malformed signature.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// Used in test case  6.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  BadSignature : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													req . Header . Set ( "authorization" ,  req . Header . Get ( "authorization" ) + "a" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// Setting an invalid Content-MD5 to force a Md5 Mismatch error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// Used in tesr case 7.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  BadMD5 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													req . Header . Set ( "Content-MD5" ,  "badmd5" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// invoke the PutObjectPart HTTP handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// validate the error response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  test . expectedAPIError  !=  noAPIErr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													var  errBytes  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// read the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													errBytes ,  err  =  ioutil . ReadAll ( rec . Result ( ) . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														t . Fatalf ( "%s, Failed to read error response from upload part request \"%s\"/\"%s\": <ERROR> %v." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															reqType ,  bucketName ,  test . objectName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// parse the XML error response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													var  errXML  APIErrorResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													err  =  xml . Unmarshal ( errBytes ,  & errXML ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														t . Fatalf ( "%s, Failed to unmarshal error response from upload part request \"%s\"/\"%s\": <ERROR> %v." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															reqType ,  bucketName ,  test . objectName ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 23:46:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													// Validate whether the error has occurred for the expected reason.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  test . expectedAPIError . Code  !=  errXML . Code  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														t . Errorf ( "%s, Expected to fail with error \"%s\", but received \"%s\"." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															reqType ,  test . expectedAPIError . Code ,  errXML . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// Validate the HTTP response status code  with the expected one.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  test . expectedAPIError . HTTPStatusCode  !=  rec . Code  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														t . Errorf ( "%s, Expected the HTTP response status code to be %d, got %d." ,  reqType ,  test . expectedAPIError . HTTPStatusCode ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Test for Anonymous/unsigned http request.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( http . MethodPut ,  getPutObjectPartURL ( "" ,  bucketName ,  testObject ,  uploadIDCopy ,  "1" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int64 ( len ( "hello" ) ) ,  bytes . NewReader ( [ ] byte ( "hello" ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s: Failed to create an anonymous request for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// unsigned request goes through and its validated again.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPIAnonTest ( t ,  obj ,  "TestAPIPutObjectPartHandler" ,  bucketName ,  testObject ,  instanceType ,  apiRouter ,  anonReq ,  getAnonWriteOnlyObjectPolicy ( bucketName ,  testObject ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HTTP request for testing when `ObjectLayer` is set to `nil`.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// There is no need to use an existing bucket and valid input for creating the request
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodPut ,  getPutObjectPartURL ( "" ,  nilBucket ,  nilObject ,  "0" ,  "0" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  bytes . NewReader ( [ ] byte ( "testNilObjLayer" ) ) ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s: Failed to create http request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` manages the operation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TestAPIListObjectPartsHandlerPreSign - Tests validate the response of ListObjectParts HTTP handler
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  when signature type of the HTTP request is `Presigned`.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPIListObjectPartsHandlerPreSign ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPIListObjectPartsHandlerPreSign , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										[ ] string { "PutObjectPart" ,  "NewMultipart" ,  "ListObjectParts" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 13:05:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  testAPIListObjectPartsHandlerPreSign ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-04-14 03:00:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2016-10-04 13:05:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testObject  :=  "testobject" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req ,  err  :=  newTestSignedRequestV4 ( http . MethodPost ,  getNewMultipartURL ( "" ,  bucketName ,  testObject ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 13:05:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] - Failed to create a signed request to initiate multipart upload for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get uploadID of the mulitpart upload initiated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  mpartResp  InitiateMultipartUploadResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mpartRespBytes ,  err  :=  ioutil . ReadAll ( rec . Result ( ) . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] Failed to read NewMultipartUpload response <ERROR> %v" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  xml . Unmarshal ( mpartRespBytes ,  & mpartResp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] Failed to unmarshal NewMultipartUpload response <ERROR> %v" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Upload a part for listing purposes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req ,  err  =  newTestSignedRequestV4 ( http . MethodPut , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 13:05:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										getPutObjectPartURL ( "" ,  bucketName ,  testObject ,  mpartResp . UploadID ,  "1" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int64 ( len ( "hello" ) ) ,  bytes . NewReader ( [ ] byte ( "hello" ) ) ,  credentials . AccessKey ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 13:05:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] - Failed to create a signed request to initiate multipart upload for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rec . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] - Failed to PutObjectPart bucket: %s object: %s HTTP status code: %d" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  testObject ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req ,  err  =  newTestRequest ( http . MethodGet , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 13:05:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										getListMultipartURLWithParams ( "" ,  bucketName ,  testObject ,  mpartResp . UploadID ,  "" ,  "" ,  "" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] - Failed to create an unsigned request to list object parts for bucket %s, uploadId %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  mpartResp . UploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-25 05:20:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req . Header  =  http . Header { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  preSignV2 ( req ,  credentials . AccessKey ,  credentials . SecretKey ,  int64 ( 10 * 60 * 60 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 13:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] - Failed to presignV2 an unsigned request to list object parts for bucket %s, uploadId %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  mpartResp . UploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rec . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Errorf ( "Test %d %s expected to succeed but failed with HTTP status code %d" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											1 ,  instanceType ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req ,  err  =  newTestRequest ( http . MethodGet , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 13:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										getListMultipartURLWithParams ( "" ,  bucketName ,  testObject ,  mpartResp . UploadID ,  "" ,  "" ,  "" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] - Failed to create an unsigned request to list object parts for bucket %s, uploadId %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  mpartResp . UploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  preSignV4 ( req ,  credentials . AccessKey ,  credentials . SecretKey ,  int64 ( 10 * 60 * 60 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 13:05:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] - Failed to presignV2 an unsigned request to list object parts for bucket %s, uploadId %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  mpartResp . UploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rec . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Errorf ( "Test %d %s expected to succeed but failed with HTTP status code %d" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											1 ,  instanceType ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TestAPIListObjectPartsHandler - Tests validate the response of ListObjectParts HTTP handler
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  for variety of success/failure cases.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPIListObjectPartsHandler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecExtendedObjectLayerAPITest ( t ,  testAPIListObjectPartsHandler ,  [ ] string { "ListObjectParts" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 13:05:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  testAPIListObjectPartsHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2022-04-14 03:00:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testObject  :=  "testobject" 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-11 00:42:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  opts  ObjectOptions 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// PutObjectPart API HTTP Handler has to be tested in isolation,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// that is without any other handler being registered,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// That's why NewMultipartUpload is initiated using ObjectLayer.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 13:31:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uploadID ,  err  :=  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  testObject ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s : <ERROR>  %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uploadIDCopy  :=  uploadID 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// create an object Part, will be used to test list object parts.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-15 09:36:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  =  obj . PutObjectPart ( context . Background ( ) ,  bucketName ,  testObject ,  uploadID ,  1 ,  mustGetPutObjReader ( t ,  bytes . NewReader ( [ ] byte ( "hello" ) ) ,  int64 ( len ( "hello" ) ) ,  "5d41402abc4b2a76b9719d911017c592" ,  "" ) ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s : %s." ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error types for invalid inputs to ListObjectParts handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									noAPIErr  :=  APIError { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error when the signature check fails.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									signatureMismatchErr  :=  getAPIError ( ErrSignatureDoesNotMatch ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error the when the uploadID is invalid.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									noSuchUploadErr  :=  getAPIError ( ErrNoSuchUpload ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error the part number marker use in the ListObjectParts request is invalid.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									invalidPartMarkerErr  :=  getAPIError ( ErrInvalidPartNumberMarker ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error when the maximum number of parts requested to listed in invalid.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									invalidMaxPartsErr  :=  getAPIError ( ErrInvalidMaxParts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fault             Fault 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										partNumberMarker  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										maxParts          string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedErr       APIError 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// case where a signature mismatch is introduced and the response is validated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :             BadSignature , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumberMarker :  "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											maxParts :          "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedErr :       signatureMismatchErr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Marker is set to invalid value of -1, error response is asserted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :             None , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumberMarker :  "-1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											maxParts :          "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedErr :       invalidPartMarkerErr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 3.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Max Parts is set a negative value, error response is validated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :             None , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumberMarker :  "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											maxParts :          "-1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedErr :       invalidMaxPartsErr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Invalid UploadID is set and the error response is validated.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fault :             MissingUploadID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partNumberMarker :  "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											maxParts :          "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedErr :       noSuchUploadErr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// string to represent V2 signed HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reqV2Str  :=  "V2 Signed HTTP request" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// string to represent V4 signed HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reqV4Str  :=  "V4 Signed HTTP request" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Collection of HTTP request and ResponseRecorder and request type string.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  inputReqRec  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req      * http . Request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec      * httptest . ResponseRecorder 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reqType  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i ,  test  :=  range  testCases  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  reqV4 ,  reqV2  * http . Request 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Using sub-tests introduced in Go 1.7.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Run ( fmt . Sprintf ( "MinIO %s: Test case %d failed." ,  instanceType ,  i + 1 ) ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											recV2  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											recV4  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// setting a non-existent uploadID.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// deliberately introducing the invalid value to be able to assert the response with the expected error response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  test . fault  ==  MissingUploadID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												uploadID  =  "upload1" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// constructing a v4 signed HTTP request for ListMultipartUploads.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reqV4 ,  err  =  newTestSignedRequestV4 ( http . MethodGet , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getListMultipartURLWithParams ( "" ,  bucketName ,  testObject ,  uploadID ,  test . maxParts ,  test . partNumberMarker ,  "" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												t . Fatalf ( "Failed to create a V4 signed request to list object parts for %s/%s: <ERROR> %v." , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Verify response of the V2 signed HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// construct HTTP request for PutObject Part Object endpoint.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reqV2 ,  err  =  newTestSignedRequestV2 ( http . MethodGet , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getListMultipartURLWithParams ( "" ,  bucketName ,  testObject ,  uploadID ,  test . maxParts ,  test . partNumberMarker ,  "" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Failed to create a V2 signed request to list object parts for %s/%s: <ERROR> %v." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// collection of input HTTP request, ResponseRecorder and request type.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqRecs  :=  [ ] inputReqRec { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													req :      reqV4 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rec :      recV4 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													reqType :  reqV4Str , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													req :      reqV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rec :      recV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													reqType :  reqV2Str , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  reqRec  :=  range  reqRecs  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Response recorder to record the response of the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rec  :=  reqRec . rec 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// HTTP request used to call the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												req  :=  reqRec . req 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// HTTP request type string for V4/V2 requests.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reqType  :=  reqRec . reqType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Malformed signature.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  test . fault  ==  BadSignature  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													req . Header . Set ( "authorization" ,  req . Header . Get ( "authorization" ) + "a" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// invoke the PutObjectPart HTTP handler with the given HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// validate the error response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  test . expectedErr  !=  noAPIErr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													var  errBytes  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// read the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													errBytes ,  err  =  ioutil . ReadAll ( rec . Result ( ) . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														t . Fatalf ( "%s,Failed to read error response list object parts request %s/%s: <ERROR> %v" ,  reqType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// parse the error response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													var  errXML  APIErrorResponse 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													err  =  xml . Unmarshal ( errBytes ,  & errXML ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														t . Fatalf ( "%s, Failed to unmarshal error response from list object partsest %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															reqType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 23:46:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													// Validate whether the error has occurred for the expected reason.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  test . expectedErr . Code  !=  errXML . Code  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														t . Errorf ( "%s, Expected to fail with %s but received %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															reqType ,  test . expectedErr . Code ,  errXML . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													// in case error is not expected response status should be 200OK.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  rec . Code  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														t . Errorf ( "%s, Expected to succeed with response HTTP status 200OK, but failed with HTTP status code %d." ,  reqType ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Test for Anonymous/unsigned http request.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( http . MethodGet , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										getListMultipartURLWithParams ( "" ,  bucketName ,  testObject ,  uploadIDCopy ,  "" ,  "" ,  "" ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "MinIO %s: Failed to create an anonymous request for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// unsigned request goes through and its validated again.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPIAnonTest ( t ,  obj ,  "TestAPIListObjectPartsHandler" ,  bucketName ,  testObject ,  instanceType ,  apiRouter ,  anonReq ,  getAnonWriteOnlyObjectPolicy ( bucketName ,  testObject ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HTTP request for testing when `objectLayer` is set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// There is no need to use an existing bucket and valid input for creating the request
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilBucket  :=  "dummy-bucket" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilObject  :=  "dummy-object" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( http . MethodGet , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										getListMultipartURLWithParams ( "" ,  nilBucket ,  nilObject ,  "dummy-uploadID" ,  "0" ,  "0" ,  "" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "MinIO %s:Failed to create http request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// execute the object layer set to `nil` test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// `ExecObjectLayerAPINilTest` sets the Object Layer to `nil` and calls the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPINilTest ( t ,  nilBucket ,  nilObject ,  instanceType ,  apiRouter ,  nilReq ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}