2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Minio  Cloud  Storage ,  ( C )  2016 ,  2017 ,  2018  Minio ,  Inc . 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Licensed  under  the  Apache  License ,  Version  2.0  ( the  "License" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  you  may  not  use  this  file  except  in  compliance  with  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  You  may  obtain  a  copy  of  the  License  at 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *      http : //www.apache.org/licenses/LICENSE-2.0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Unless  required  by  applicable  law  or  agreed  to  in  writing ,  software 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  distributed  under  the  License  is  distributed  on  an  "AS IS"  BASIS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  WITHOUT  WARRANTIES  OR  CONDITIONS  OF  ANY  KIND ,  either  express  or  implied . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  See  the  License  for  the  specific  language  governing  permissions  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  limitations  under  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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" 
							 
						 
					
						
							
								
									
										
										
										
											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" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
									
										
										
										
											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" 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/pkg/auth" 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling HeadObject API handler tests for both XL multiple disks and FS single drive setup.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPIHeadObjectHandler ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPIHeadObjectHandler ,  [ ] string { "HeadObject" } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPIHeadObjectHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  :=  obj . PutObject ( context . Background ( ) ,  input . bucketName ,  input . objectName ,  mustGetHashReader ( t ,  bytes . NewBuffer ( input . textData ) ,  input . contentLength ,  input . metaData [ "" ] ,  "" ) ,  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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req ,  err  :=  newTestSignedRequestV4 ( "HEAD" ,  getHeadObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reqV2 ,  err  :=  newTestSignedRequestV2 ( "HEAD" ,  getHeadObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( "HEAD" ,  getHeadObjectURL ( "" ,  bucketName ,  objectName ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Minio %s: Failed to create an anonymous request for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( "HEAD" ,  getGetObjectURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Errorf ( "Minio %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Wrapper for calling GetObject API handler tests for both XL multiple disks and FS single drive setup.
  
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  TestAPIGetObjectHandler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( 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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  :=  obj . PutObject ( context . Background ( ) ,  input . bucketName ,  input . objectName ,  mustGetHashReader ( t ,  bytes . NewBuffer ( input . textData ) ,  input . contentLength ,  input . metaData [ "" ] ,  "" ) ,  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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedContent :     encodeResponse ( getAPIErrorResponse ( getAPIError ( ErrNoSuchKey ) ,  getGetObjectURL ( "" ,  bucketName ,  "abcd" ) ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											expectedContent :     encodeResponse ( getAPIErrorResponse ( getAPIError ( ErrInvalidRange ) ,  getGetObjectURL ( "" ,  bucketName ,  objectName ) ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :     encodeResponse ( getAPIErrorResponse ( getAPIError ( ErrInvalidAccessKeyID ) ,  getGetObjectURL ( "" ,  bucketName ,  objectName ) ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( getAPIError ( ErrInvalidObjectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  "../../etc" ) ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( getAPIError ( ErrNoSuchKey ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"/" + bucketName + "/" + ". ./. ./etc" ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 9.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with bad components in object name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  ". ./../etc" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( getAPIError ( ErrInvalidObjectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"/" + bucketName + "/" + ". ./../etc" ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 10.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Case with proper components
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											objectName :  "etc/path/proper/.../etc" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											byteRange :   "" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :   credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :   credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( getAPIError ( ErrNoSuchKey ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  "etc/path/proper/.../etc" ) ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  :=  newTestSignedRequestV4 ( "GET" ,  getGetObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Add ( "Range" ,  testCase . byteRange ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed parsing response body: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Verify whether the bucket obtained object is same as the one created.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ! bytes . Equal ( testCase . expectedContent ,  actualContent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-25 09:13:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "Test %d: %s: Object content differs from expected value %s, got %s" ,  i + 1 ,  instanceType ,  testCase . expectedContent ,  string ( actualContent ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reqV2 ,  err  :=  newTestSignedRequestV2 ( "GET" ,  getGetObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed to create HTTP request for GetObject: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . byteRange  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . Header . Add ( "Range" ,  testCase . byteRange ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d: %s: Failed parsing response body: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( "GET" ,  getGetObjectURL ( "" ,  bucketName ,  objectName ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( "GET" ,  getGetObjectURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling PutObject API handler tests using streaming signature v4 for both XL multiple disks and FS single drive setup.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPIPutObjectStreamSigV4Handler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( 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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											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 , 
							 
						 
					
						
							
								
									
										
										
										
											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 { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusInternalServerError , 
							 
						 
					
						
							
								
									
										
										
										
											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 { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusInternalServerError , 
							 
						 
					
						
							
								
									
										
										
										
											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" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req ,  err  =  newTestStreamingSignedBadChunkDateRequest ( "PUT" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												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  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req ,  err  =  newTestStreamingSignedRequest ( "PUT" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												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  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req ,  err  =  newTestStreamingSignedCustomEncodingRequest ( "PUT" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												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  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "Test %d %s: Expected the response status to be `%d`, but instead found `%d`" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objInfo ,  err  :=  obj . GetObjectInfo ( context . Background ( ) ,  testCase . bucketName ,  testCase . objectName ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  obj . GetObject ( context . Background ( ) ,  testCase . bucketName ,  testCase . objectName ,  0 ,  int64 ( testCase . dataLen ) ,  buffer ,  objInfo . ETag ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buffer . Reset ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Wrapper for calling PutObject API handler tests for both XL multiple disks and FS single drive setup.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPIPutObjectHandler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( 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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectName  :=  "test-object" 
							 
						 
					
						
							
								
									
										
										
										
											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 { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									inalidStorageClassHeader . Set ( 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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( "PUT" ,  getPutObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int64 ( testCase . dataLen ) ,  bytes . NewReader ( testCase . data ) ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  obj . GetObject ( context . Background ( ) ,  testCase . bucketName ,  testCase . objectName ,  0 ,  int64 ( len ( bytesData ) ) ,  buffer ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reqV2 ,  err  =  newTestSignedRequestV2 ( "PUT" ,  getPutObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int64 ( testCase . dataLen ) ,  bytes . NewReader ( testCase . data ) ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  obj . GetObject ( context . Background ( ) ,  testCase . bucketName ,  testCase . objectName ,  0 ,  int64 ( len ( bytesData ) ) ,  buffer ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( "PUT" ,  getPutObjectURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int64 ( len ( "hello" ) ) ,  bytes . NewReader ( [ ] byte ( "hello" ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( "PUT" ,  getPutObjectURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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 ) ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPICopyObjectPartHandlerSanity ,  [ ] string { "CopyObjectPart" } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPICopyObjectPartHandlerSanity ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +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 
							 
						 
					
						
							
								
									
										
										
										
											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 , 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											mustGetHashReader ( t ,  bytes . NewBuffer ( input . textData ) ,  input . contentLength ,  input . metaData [ "" ] ,  "" ) ,  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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uploadID ,  err  :=  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  testObject ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Minio %s : <ERROR>  %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a  :=  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									b  :=  globalMinPartSize  -  1 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( "PUT" ,  cpPartURL ,  0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										a  =  globalMinPartSize 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									result ,  err  :=  obj . CompleteMultipartUpload ( context . Background ( ) ,  bucketName ,  testObject ,  uploadID ,  parts ) 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  obj . GetObject ( context . Background ( ) ,  bucketName ,  testObject ,  0 ,  int64 ( len ( bytesData [ 0 ] . byteData ) ) ,  & buf ,  "" ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-04 08:32:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "Test: %s reading completed file failed: <ERROR> %v" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! bytes . Equal ( buf . Bytes ( ) ,  bytesData [ 0 ] . byteData )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Test: %s returned data is not expected corruption detected:" ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling Copy Object Part API handler tests for both XL multiple disks and single node setup.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPICopyObjectPartHandler ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPICopyObjectPartHandler ,  [ ] string { "CopyObjectPart" } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPICopyObjectPartHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +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 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  obj . PutObject ( context . Background ( ) ,  input . bucketName ,  input . objectName ,  mustGetHashReader ( t ,  bytes . NewBuffer ( input . textData ) ,  input . contentLength ,  input . metaData [ "" ] ,  "" ) ,  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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uploadID ,  err  :=  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  testObject ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Minio %s : <ERROR>  %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// test cases with inputs and expected result for Copy Object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// expected output.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedRespStatus  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 1, copy part 1 from from newObject1, ignore request headers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :            uploadID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with invalid source object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  testObject ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :         credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :         credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusNotFound , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case - 4.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Test case with valid byte range.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uploadID :          uploadID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  "non-existent-object" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											maximumPartNumber :   true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :           credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :           credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :  http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  testCase  :=  range  testCases  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  req  * http . Request 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  reqV2  * 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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req ,  err  =  newTestSignedRequestV4 ( "PUT" ,  getCopyObjectPartURL ( "" ,  testCase . bucketName ,  testObject ,  testCase . uploadID ,  "1" ) ,  0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  testCase . invalidPartNumber  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req ,  err  =  newTestSignedRequestV4 ( "PUT" ,  getCopyObjectPartURL ( "" ,  testCase . bucketName ,  testObject ,  testCase . uploadID ,  "abc" ) ,  0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  testCase . maximumPartNumber  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req ,  err  =  newTestSignedRequestV4 ( "PUT" ,  getCopyObjectPartURL ( "" ,  testCase . bucketName ,  testObject ,  testCase . uploadID ,  "99999" ) ,  0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											req . Header . Set ( "X-Amz-Copy-Source-Range" ,  testCase . copySourceRange ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 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 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											results ,  err  =  obj . ListObjectParts ( context . Background ( ) ,  testCase . bucketName ,  testObject ,  testCase . uploadID ,  0 ,  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-05 01:45:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  instanceType  !=  FSTestStr  &&  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 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Verify response of the V2 signed HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										recV2  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reqV2 ,  err  =  newTestRequest ( "PUT" ,  getCopyObjectPartURL ( "" ,  testCase . bucketName ,  testObject ,  testCase . uploadID ,  "1" ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . Header . Set ( "X-Amz-Copy-Source" ,  testCase . copySourceHeader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  testCase . copySourceRange  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 . Header . Set ( "X-Amz-Copy-Source-Range" ,  testCase . copySourceRange ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "Test %d: %s: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  recV2 . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( "PUT" ,  getCopyObjectPartURL ( "" ,  nilBucket ,  nilObject ,  "0" ,  "0" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  bytes . NewReader ( [ ] byte ( "testNilObjLayer" ) ) ,  "" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Errorf ( "Minio %s: Failed to create http request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Below is how CopyObjectPartHandler is registered.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?").HandlerFunc(api.CopyObjectPartHandler).Queries("partNumber", "{partNumber:[0-9]+}", "uploadId", "{uploadId:.*}")
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Its necessary to set the "X-Amz-Copy-Source" header for the request to be accepted by the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq . Header . Set ( "X-Amz-Copy-Source" ,  url . QueryEscape ( "/" + nilBucket + "/" + nilObject ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Wrapper for calling Copy Object API handler tests for both XL multiple disks and single node setup.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPICopyObjectHandler ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( 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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectName  :=  "test-object" 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 10:18:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ generateBytesData ( 6  *  humanize . KiByte ) } , 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// used for anonymous HTTP request test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  anonObject ,  int64 ( len ( bytesData [ 0 ] . byteData ) ) ,  bytesData [ 0 ] . byteData ,  make ( map [ string ] string ) } , 
							 
						 
					
						
							
								
									
										
										
										
											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-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  obj . PutObject ( context . Background ( ) ,  input . bucketName ,  input . objectName ,  mustGetHashReader ( t ,  bytes . NewBuffer ( input . textData ) ,  input . contentLength ,  input . metaData [ "" ] ,  "" ) ,  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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 08:29:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Test case - 1, copy metadata from newObject1, ignore request headers.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     "newObject1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     "newObject1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/" ) , 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  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 . 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
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     "newObject1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											metadata :  map [ string ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"Content-Type" :  "application/json" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											metadataCopy :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :     credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :     credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  "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).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucketName :        "non-existent-destination-bucket" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :        bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :     objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :  url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :       "newObject1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :       "newObject1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :          bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :       "newObject1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :    url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :            bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :         "newObject1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :      url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :            bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :         "newObject1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :      url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucketName :            bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newObjectName :         "newObject1" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copySourceHeader :      url . QueryEscape ( "/"  +  bucketName  +  "/"  +  objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											copyUnmodifiedHeader :  "Mon, 02 Jan 2007 15:04:05 +00:00" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											accessKey :             credentials . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											secretKey :             credentials . SecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedRespStatus :    http . StatusOK , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( "PUT" ,  getCopyObjectURL ( "" ,  testCase . bucketName ,  testCase . newObjectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 object is formed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// testing whether the copy was successful.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  obj . GetObject ( context . Background ( ) ,  testCase . bucketName ,  testCase . newObjectName ,  0 ,  int64 ( len ( bytesData [ 0 ] . byteData ) ) ,  buffers [ 0 ] ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Test %d: %s: Failed to fetch the copied object: <ERROR> %s" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 + 1 ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buffers [ 0 ] . Reset ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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 ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reqV2 ,  err  =  newTestRequest ( "PUT" ,  getCopyObjectURL ( "" ,  testCase . bucketName ,  testCase . newObjectName ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "Test %d: %s: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  recV2 . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newCopyAnonObject  :=  "new-anon-obj" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( "PUT" ,  getCopyObjectURL ( "" ,  bucketName ,  newCopyAnonObject ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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 ,  "new-anon-obj" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Below is how CopyObjectHandler is registered.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?")
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Its necessary to set the "X-Amz-Copy-Source" header for the request to be accepted by the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq . Header . Set ( "X-Amz-Copy-Source" ,  url . QueryEscape ( "/" + bucketName + "/" + anonObject ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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 ,  "TestAPICopyObjectHandler" ,  bucketName ,  newCopyAnonObject ,  instanceType ,  apiRouter ,  anonReq ,  getAnonWriteOnlyObjectPolicy ( bucketName ,  newCopyAnonObject ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( "PUT" ,  getCopyObjectURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Below is how CopyObjectHandler is registered.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// bucket.Methods("PUT").Path("/{object:.+}").HeadersRegexp("X-Amz-Copy-Source", ".*?(\\/|%2F).*?")
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Its necessary to set the "X-Amz-Copy-Source" header for the request to be accepted by the handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq . Header . Set ( "X-Amz-Copy-Source" ,  url . QueryEscape ( "/" + nilBucket + "/" + nilObject ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Wrapper for calling NewMultipartUpload tests for both XL multiple disks and single node setup.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req ,  err  :=  newTestSignedRequestV4 ( "POST" ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  =  obj . ListObjectParts ( context . Background ( ) ,  bucketName ,  objectName ,  multipartResponse . UploadID ,  0 ,  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  =  newTestSignedRequestV4 ( "POST" ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "Invalid-AccessID" ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reqV2 ,  err  :=  newTestSignedRequestV2 ( "POST" ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  =  obj . ListObjectParts ( context . Background ( ) ,  bucketName ,  objectName ,  multipartResponse . UploadID ,  0 ,  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reqV2 ,  err  =  newTestSignedRequestV2 ( "POST" ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  "Invalid-AccessID" ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( "POST" ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( "POST" ,  getNewMultipartURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Wrapper for calling NewMultipartUploadParallel tests for both XL multiple disks and single node setup.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req ,  err  :=  newTestSignedRequestV4 ( "POST" ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) ,  0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ( "Minio %s:  Expected the response status to be `%d`, but instead found `%d`" ,  instanceType ,  http . StatusOK ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// decode the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											decoder  :=  xml . NewDecoder ( rec . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											multipartResponse  :=  & InitiateMultipartUploadResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  decoder . Decode ( multipartResponse ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Minio %s: Error decoding the recorded response Body" ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// 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  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  :=  obj . ListObjectParts ( context . Background ( ) ,  bucketName ,  objectName ,  uploadID ,  0 ,  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										uploadID ,  err  =  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  objectName ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Minio %s : <ERROR>  %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  5 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( string ( validPart ) ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  6 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( string ( 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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 1 ] ,  1 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( string ( validPart ) ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 1 ] ,  2 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( string ( 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 , 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											mustGetHashReader ( t ,  bytes . NewBufferString ( part . inputReaderData ) ,  part . intputDataSize ,  part . inputMd5 ,  "" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s3MD5 ,  err  :=  getCompleteMultipartMD5 ( context . Background ( ) ,  inputParts [ 3 ] . parts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Obtaining S3MD5 failed" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-18 02:20:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( getAPIError ( toAPIErrorCode ( InvalidPart { } ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  objectName ) ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( getAPIError ( toAPIErrorCode ( 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( completeMultipartAPIError { int64 ( 4 ) ,  int64 ( 5242880 ) ,  1 ,  "e2fc714c4727ee9395f324cd2e7f331f" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getAPIErrorResponse ( getAPIError ( toAPIErrorCode ( PartTooSmall { PartNumber :  1 } ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													getGetObjectURL ( "" ,  bucketName ,  objectName ) ) } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( getAPIError ( toAPIErrorCode ( 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedContent :  encodeResponse ( getAPIErrorResponse ( getAPIError ( ErrInvalidAccessKeyID ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getGetObjectURL ( "" ,  bucketName ,  objectName ) ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( "POST" ,  getCompleteMultipartUploadURL ( "" ,  bucketName ,  objectName ,  testCase . uploadID ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int64 ( len ( completeBytes ) ) ,  bytes . NewReader ( completeBytes ) ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "Case %d: Minio %s: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// 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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Test %d : Minio %s: Failed parsing response body: <ERROR> %v" ,  i + 1 ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 15:09:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Verify whether the bucket obtained object is same as the one created.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! bytes . Equal ( testCase . expectedContent ,  actualContent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "Test %d : Minio %s: Object content differs from expected value." ,  i + 1 ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( "POST" ,  getCompleteMultipartUploadURL ( "" ,  bucketName ,  objectName ,  uploadIDs [ 1 ] ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int64 ( len ( completeBytes ) ) ,  bytes . NewReader ( completeBytes ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( "POST" ,  getCompleteMultipartUploadURL ( "" ,  nilBucket ,  nilObject ,  "dummy-uploadID" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										uploadID ,  err  =  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  objectName ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Minio %s : <ERROR>  %s" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  5 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( string ( validPart ) ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 0 ] ,  6 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( string ( validPart ) ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 1 ] ,  1 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( string ( validPart ) ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ bucketName ,  objectName ,  uploadIDs [ 1 ] ,  2 ,  string ( validPart ) ,  validPartMD5 ,  int64 ( len ( string ( validPart ) ) ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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 , 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											mustGetHashReader ( t ,  bytes . NewBufferString ( part . inputReaderData ) ,  part . intputDataSize ,  part . inputMd5 ,  "" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( "DELETE" ,  getAbortMultipartUploadURL ( "" ,  testCase . bucket ,  testCase . object ,  testCase . uploadID ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "Case %d: Minio %s: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 ,  instanceType ,  testCase . expectedRespStatus ,  rec . Code ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create unsigned HTTP request for Abort multipart upload.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( "DELETE" ,  getAbortMultipartUploadURL ( "" ,  bucketName ,  objectName ,  uploadIDs [ 1 ] ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Minio %s: Failed to create an anonymous request for %s/%s: <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( "DELETE" ,  getAbortMultipartUploadURL ( "" ,  nilBucket ,  nilObject ,  "dummy-uploadID" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Errorf ( "Minio %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`." ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Wrapper for calling Delete Object API handler tests for both XL 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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 11:08:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  err  =  obj . PutObject ( context . Background ( ) ,  input . bucketName ,  input . objectName ,  mustGetHashReader ( t ,  bytes . NewBuffer ( input . textData ) ,  input . contentLength ,  input . metaData [ "" ] ,  "" ) ,  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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  =  newTestSignedRequestV4 ( "DELETE" ,  getDeleteObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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-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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reqV2 ,  err  =  newTestSignedRequestV2 ( "DELETE" ,  getDeleteObjectURL ( "" ,  testCase . bucketName ,  testCase . objectName ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											0 ,  nil ,  testCase . accessKey ,  testCase . secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Errorf ( "Case %d: Minio %s: Expected the response status to be `%d`, but instead found `%d`" ,  i + 1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( "DELETE" ,  getDeleteObjectURL ( "" ,  bucketName ,  anonObjectName ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( "DELETE" ,  getDeleteObjectURL ( "" ,  nilBucket ,  nilObject ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TestAPIPutObjectPartHandlerPreSign - Tests validate the response of PutObjectPart HTTP handler
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// when the request signature type is PreSign.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestAPIPutObjectPartHandlerPreSign ( t  * testing . T )  {  
						 
					
						
							
								
									
										
										
										
											2016-11-07 13:53:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  DetectTestLeak ( t ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPIPutObjectPartHandlerPreSign ,  [ ] string { "NewMultipart" ,  "PutObjectPart" } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 13:05:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  testAPIPutObjectPartHandlerPreSign ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 13:05:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testObject  :=  "testobject" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  newTestSignedRequestV4 ( "POST" ,  getNewMultipartURL ( "" ,  bucketName ,  "testobject" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  =  newTestRequest ( "PUT" ,  getPutObjectPartURL ( "" ,  bucketName ,  testObject ,  mpartResp . UploadID ,  "1" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int64 ( len ( "hello" ) ) ,  bytes . NewReader ( [ ] byte ( "hello" ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] - Failed to create an unsigned request to put object part for %s/%s <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-25 05:20:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 presign an unsigned request to put object part for %s/%s <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  =  newTestRequest ( "PUT" ,  getPutObjectPartURL ( "" ,  bucketName ,  testObject ,  mpartResp . UploadID ,  "1" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int64 ( len ( "hello" ) ) ,  bytes . NewReader ( [ ] byte ( "hello" ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "[%s] - Failed to create an unsigned request to put object part for %s/%s <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											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 presign an unsigned request to put object part for %s/%s <ERROR> %v" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											instanceType ,  bucketName ,  testObject ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 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 ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPIPutObjectPartHandlerStreaming ,  [ ] string { "NewMultipart" ,  "PutObjectPart" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPIPutObjectPartHandlerStreaming ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testObject  :=  "testobject" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  newTestSignedRequestV4 ( "POST" ,  getNewMultipartURL ( "" ,  bucketName ,  "testobject" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									internalErr  :=  getAPIError ( ErrInternalError ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testCases  :=  [ ] struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fault        Fault 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedErr  APIError 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ BadSignature ,  missingDateHeaderErr } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ None ,  noAPIErr } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ TooBigDecodedLength ,  internalErr } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  test  :=  range  testCases  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req ,  err  =  newTestStreamingSignedRequest ( "PUT" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( t ,  testAPIPutObjectPartHandler ,  [ ] string { "PutObjectPart" } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  testAPIPutObjectPartHandler ( obj  ObjectLayer ,  instanceType ,  bucketName  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Initiate Multipart upload for testing PutObjectPartHandler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testObject  :=  "testobject" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uploadID ,  err  :=  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  testObject ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Run ( fmt . Sprintf ( "Minio %s : Test case %d." ,  instanceType ,  i + 1 ) ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reqV4 ,  err  =  newTestSignedRequestV4 ( "PUT" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getPutObjectPartURL ( "" ,  bucketName ,  test . objectName ,  uploadID ,  test . partNumber ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												0 ,  test . reader ,  test . accessKey ,  test . secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 ,  err  =  newTestSignedRequestV2 ( "PUT" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getPutObjectPartURL ( "" ,  bucketName ,  test . objectName ,  uploadID ,  test . partNumber ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												0 ,  test . reader ,  test . accessKey ,  test . secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( "PUT" ,  getPutObjectPartURL ( "" ,  bucketName ,  testObject ,  uploadIDCopy ,  "1" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int64 ( len ( "hello" ) ) ,  bytes . NewReader ( [ ] byte ( "hello" ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( "PUT" ,  getPutObjectPartURL ( "" ,  nilBucket ,  nilObject ,  "0" ,  "0" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  bytes . NewReader ( [ ] byte ( "testNilObjLayer" ) ) ,  "" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-04 13:05:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testObject  :=  "testobject" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  newTestSignedRequestV4 ( "POST" ,  getNewMultipartURL ( "" ,  bucketName ,  testObject ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  =  newTestSignedRequestV4 ( "PUT" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										getPutObjectPartURL ( "" ,  bucketName ,  testObject ,  mpartResp . UploadID ,  "1" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int64 ( len ( "hello" ) ) ,  bytes . NewReader ( [ ] byte ( "hello" ) ) ,  credentials . AccessKey ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  =  newTestRequest ( "GET" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  =  newTestRequest ( "GET" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ExecObjectLayerAPITest ( 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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  auth . Credentials ,  t  * testing . T )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testObject  :=  "testobject" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uploadID ,  err  :=  obj . NewMultipartUpload ( context . Background ( ) ,  bucketName ,  testObject ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Failed to create NewMultipartUpload, abort.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  =  obj . PutObjectPart ( context . Background ( ) ,  bucketName ,  testObject ,  uploadID ,  1 ,  mustGetHashReader ( t ,  bytes . NewReader ( [ ] byte ( "hello" ) ) ,  int64 ( len ( "hello" ) ) ,  "5d41402abc4b2a76b9719d911017c592" ,  "" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-15 11:52:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reqV4 ,  err  =  newTestSignedRequestV4 ( "GET" , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 11:16:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getListMultipartURLWithParams ( "" ,  bucketName ,  testObject ,  uploadID ,  test . maxParts ,  test . partNumberMarker ,  "" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reqV2 ,  err  =  newTestSignedRequestV2 ( "GET" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getListMultipartURLWithParams ( "" ,  bucketName ,  testObject ,  uploadID ,  test . maxParts ,  test . partNumberMarker ,  "" ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												0 ,  nil ,  credentials . AccessKey ,  credentials . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq ,  err  :=  newTestRequest ( "GET" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										getListMultipartURLWithParams ( "" ,  bucketName ,  testObject ,  uploadIDCopy ,  "" ,  "" ,  "" ) ,  0 ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nilReq ,  err  :=  newTestSignedRequestV4 ( "GET" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										getListMultipartURLWithParams ( "" ,  nilBucket ,  nilObject ,  "dummy-uploadID" ,  "0" ,  "0" ,  "" ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										0 ,  nil ,  "" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}