2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Minio  Cloud  Storage ,  ( C )  2015 ,  2016 ,  2017  Minio ,  Inc . 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +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-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"bufio" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/ecdsa" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/hmac" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									crand  "crypto/rand" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"crypto/rsa" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/sha1" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:30:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/tls" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/x509" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"crypto/x509/pkix" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"encoding/base64" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"encoding/hex" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-16 07:13:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"encoding/json" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/pem" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-16 07:13:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"io/ioutil" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"math/big" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"math/rand" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"net/http/httptest" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"os" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-17 04:06:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"reflect" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"sort" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-29 18:13:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-29 18:13:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"testing" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/fatih/color" 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									router  "github.com/gorilla/mux" 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-08 10:50:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Tests should initNSLock only once.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  init ( )  {  
						 
					
						
							
								
									
										
										
										
											2016-12-23 23:12:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set as non-distributed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalIsDistXL  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-08 10:50:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Initialize name space lock.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-23 23:12:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									initNSLock ( globalIsDistXL ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Disable printing console messages during tests.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									color . Output  =  ioutil . Discard 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-09 12:35:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-03 02:34:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set system resources to maximum.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									setMaxResources ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-08 10:50:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  prepareFS ( )  ( ObjectLayer ,  string ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nDisks  :=  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fsDirs ,  err  :=  getRandomDisks ( nDisks ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									obj ,  err  :=  newFSObjectLayer ( fsDirs [ 0 ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  obj ,  fsDirs [ 0 ] ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  prepareXL ( )  ( ObjectLayer ,  [ ] string ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nDisks  :=  16 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fsDirs ,  err  :=  getRandomDisks ( nDisks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									endpoints ,  err  :=  parseStorageEndpoints ( fsDirs ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-19 03:49:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-12 08:36:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									obj ,  _ ,  err  :=  initObjectLayer ( endpoints ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										removeRoots ( fsDirs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  obj ,  fsDirs ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Initialize FS objects.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  initFSObjects ( disk  string ,  t  * testing . T )  ( obj  ObjectLayer )  {  
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newTestConfig ( globalMinioDefaultRegion ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									obj ,  err  =  newFSObjectLayer ( disk ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  obj 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 11:39:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// TestErrHandler - Golang Testing.T and Testing.B, and gocheck.C satisfy this interface.
  
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// This makes it easy to run the TestServer from any of the tests.
  
						 
					
						
							
								
									
										
										
										
											2016-07-26 11:39:14 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Using this interface, functionalities to be used in tests can be made generalized, and can be integrated in benchmarks/unit tests/go check suite tests.
  
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  TestErrHandler  interface  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Error ( args  ... interface { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Errorf ( format  string ,  args  ... interface { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Failed ( )  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Fatal ( args  ... interface { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Fatalf ( format  string ,  args  ... interface { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
									
										
										
										
											2016-11-02 01:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// FSTestStr is the string which is used as notation for Single node ObjectLayer in the unit tests.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FSTestStr  string  =  "FS" 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-02 01:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// XLTestStr is the string which is used as notation for XL ObjectLayer in the unit tests.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									XLTestStr  string  =  "XL" 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								const  letterBytes  =  "abcdefghijklmnopqrstuvwxyz01234569"  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									letterIdxBits  =  6                     // 6 bits to represent a letter index
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									letterIdxMask  =  1 << letterIdxBits  -  1  // All 1-bits, as many as letterIdxBits
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									letterIdxMax   =  63  /  letterIdxBits    // # of letter indices fitting in 63 bits
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-29 18:13:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Random number state.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// We generate random temporary file names so that there's a good
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// chance the file doesn't exist yet.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  randN  uint32  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  randmu  sync . Mutex  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 14:25:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Temp files created in default Tmp dir
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  globalTestTmpDir  =  os . TempDir ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-02 16:59:28 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// reseed - returns a new seed every time the function is called.
  
						 
					
						
							
								
									
										
										
										
											2016-06-29 18:13:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  reseed ( )  uint32  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  uint32 ( time . Now ( ) . UnixNano ( )  +  int64 ( os . Getpid ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-02 16:59:28 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// nextSuffix - provides a new unique suffix every time the function is called.
  
						 
					
						
							
								
									
										
										
										
											2016-06-29 18:13:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  nextSuffix ( )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									randmu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r  :=  randN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Initial seed required, generate one.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  r  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r  =  reseed ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// constants from Numerical Recipes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r  =  r * 1664525  +  1013904223 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									randN  =  r 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									randmu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  strconv . Itoa ( int ( 1e9  +  r % 1e9 ) ) [ 1 : ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-17 04:06:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// isSameType - compares two object types via reflect.TypeOf
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  isSameType ( obj1 ,  obj2  interface { } )  bool  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  reflect . TypeOf ( obj1 )  ==  reflect . TypeOf ( obj2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// TestServer encapsulates an instantiation of a Minio instance with a temporary backend.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Example usage:
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//   s := StartTestServer(t,"XL")
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//   defer s.Stop()
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  TestServer  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Root       string 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Disks      [ ] * url . URL 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									AccessKey  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SecretKey  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Server     * httptest . Server 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Obj        ObjectLayer 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 16:03:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									SrvCmdCfg  serverCmdConfig 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// UnstartedTestServer - Configures a temp FS/XL backend,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// initializes the endpoints and configures the test server.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The server should be started using the Start() method.
  
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:30:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  UnstartedTestServer ( t  TestErrHandler ,  instanceType  string )  TestServer  {  
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// create an instance of TestServer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testServer  :=  TestServer { } 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// return FS/XL object layer and temp backend.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objLayer ,  disks ,  err  :=  prepareTestBackend ( instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatal ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// set the server configuration.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									root ,  err  :=  newTestConfig ( globalMinioDefaultRegion ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Test Server needs to start before formatting of disks.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Get credential.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									credentials  :=  serverConfig . GetCredential ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . Obj  =  objLayer 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . Disks ,  err  =  parseStorageEndpoints ( disks ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-19 03:49:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "Unexpected error %v" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-19 03:49:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . Root  =  root 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . AccessKey  =  credentials . AccessKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testServer . SecretKey  =  credentials . SecretKey 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									srvCmdCfg  :=  serverCmdConfig { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										endpoints :  testServer . Disks , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-13 14:13:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									httpHandler ,  err  :=  configureServerHandler ( 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										srvCmdCfg , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-13 14:13:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Failed to configure one of the RPC services <ERROR> %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Run TestServer.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:30:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . Server  =  httptest . NewUnstartedServer ( httpHandler ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// obtain server address.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									srvCmdCfg . serverAddr  =  testServer . Server . Listener . Addr ( ) . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 14:03:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjLayerMutex . Lock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjectAPI  =  objLayer 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 14:03:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjLayerMutex . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// initialize peer rpc
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									host ,  port ,  err  :=  net . SplitHostPort ( srvCmdCfg . serverAddr ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Early setup error:" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalMinioHost  =  host 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalMinioPort  =  port 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalMinioAddr  =  getLocalAddress ( srvCmdCfg ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									endpoints ,  err  :=  parseStorageEndpoints ( disks ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-19 03:49:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Early setup error:" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									initGlobalS3Peers ( endpoints ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  testServer 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:30:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// testServerCertPEM and testServerKeyPEM are generated by
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  https://golang.org/src/crypto/tls/generate_cert.go
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//    $ go run generate_cert.go -ca --host 127.0.0.1
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The generated certificate contains IP SAN, that way we don't need
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// to enable InsecureSkipVerify in TLS config
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  testServerCertPEM  =  [ ] byte ( ` -- -- - BEGIN  CERTIFICATE -- -- -  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MIIC9zCCAd + gAwIBAgIQV9ukx5ZahXeFygLXnR1WJTANBgkqhkiG9w0BAQsFADAS  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MRAwDgYDVQQKEwdBY21lIENvMB4XDTE2MTExNTE1MDQxNFoXDTE3MTExNTE1MDQx  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NFowEjEQMA4GA1UEChMHQWNtZSBDbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AQoCggEBALLDXunOVIipgtvPVpQxIBTzUpceUtLYrNKTCtYfLtvFCNSPAa2W2EAi  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								mW2WgtU + Wd + jFN2leG + lvyEp2n1YzBN12oOzAZMf39K2j05aO6vN68Pf / 3 w / h2qz  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								PDYFWbWBMS1vC6RosfaQc4VFZCkz89M1aonwj0K8FjOHG4pu7rKnVkluC0c4 + Xpu  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								8 rB652chx / h6wFZwscVqFZIarTte8Z1tcbRhbvpdkOV749Wn5i2umlrKpBgsBv22  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								8 jn115BK7E2mN0rlCYPuN312bFFSSE85NaSdOp06TjD + 2 Rv9jPKizvnFN + 2 ADEje  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								nlCaYe3VRybKPZLrxPcqFQoCQsO + 8 ZsCAwEAAaNJMEcwDgYDVR0PAQH / BAQDAgKk  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB / wQFMAMBAf8wDwYDVR0RBAgw  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								BocEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAsmNCixmx + srB93 + Jz5t90zzCJN4O  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								5 RDWh7X7D54xtRRZ / t9HLLLFKW9EqhAM17xee3C4eNCicOqHP / htEvLwt3BWFmya  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								djvIUQYfymx4GtBTfMH4eC5vYGdxSuTVNe7JGHMpJjArNe4vIlUHyj2n12aGDHUf  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NKEiTR2m + 6 hiKEyym74vhxGnl208OFa4tAMv3J7BjEObE37oy / vH / getE0HwG / EL  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								feE4D2Pp9XqeMCg / sPZPoQgBuq3QsL2RdL8DQywb / HrApdLyfmN0avV5tmbrm0cL  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/ 0 NUqCWjJIIKF0XxZbqlkQsYK5zpDJ36MFXO65aF3QGOMP1rlBD3d0S6kw ==  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								-- -- - END  CERTIFICATE -- -- - ` )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  testServerKeyPEM  =  [ ] byte ( ` -- -- - BEGIN  RSA  PRIVATE  KEY -- -- -  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MIIEowIBAAKCAQEAssNe6c5UiKmC289WlDEgFPNSlx5S0tis0pMK1h8u28UI1I8B  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								rZbYQCKZbZaC1T5Z36MU3aV4b6W / ISnafVjME3Xag7MBkx / f0raPTlo7q83rw9 //
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								fD + HarM8NgVZtYExLW8LpGix9pBzhUVkKTPz0zVqifCPQrwWM4cbim7usqdWSW4L  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Rzj5em7ysHrnZyHH + HrAVnCxxWoVkhqtO17xnW1xtGFu + l2Q5Xvj1afmLa6aWsqk  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								GCwG / bbyOfXXkErsTaY3SuUJg + 43 fXZsUVJITzk1pJ06nTpOMP7ZG / 2 M8qLO + cU3  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								7 YAMSN6eUJph7dVHJso9kuvE9yoVCgJCw77xmwIDAQABAoIBAEE6CmLTd4LaHzZn  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								RBcUibk7Q5KCbQQkLYM0Rgr1G9ry3RL6D0mwtb1JIqSa + 6 gldROl5NIvM2 / Bkajf  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								JasBAI3FPfM6GMP / KGMxW77iK823eGRjUkyavaWQOtMXRrF0r2X9k8jsrqrh8FTb  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if2CyF / zqKkmTo + yI4Ovs7viWFR1IFBUHRwfYTTKnXA2q4S39knExALe1wWUkc4L  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								oOidewQ5IVCU3OQLWXP / beKoV / jw6 + dOs5CYjXFsww6tdOsh + WkA9d3 / rKPPtLdP  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								tDQiZtmI6FCYy / PdYqmzY0xg6dipGTDRfENUEx5SJu6HeSoUQUwEpQqnRxIu0iZl  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								FJ2ZziECgYEAzpdbIrFltGlSh7DIJfnQG86QeOw / nGluFTED9AweRAIzOYnUQCV3  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								XCKMhFqmzsNpibEC1Cok92ZJk7bfsmPlx + qzL7BFpynA / gezxgc2wNZlWs8btPHi  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								s9h8hwL5If1FgAMD4E2iJtNgI / Kn5j8SDo / A5hAP1CXv12JRTB + pzlECgYEA3YQ6  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								e2MLQYLDIcD5RoCrXOc9qo / l46uzo5laIuCKtd / IoOlip95kdgzpQC0 / eenDLV9y  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								KLqAOZxZe + TVKtSOzVGy58FyD6L1oBJgfwuBku1x5ADRsIblq2uIOumDygRU0hMg  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								0 tM3orIFGLyJU5hv6vC0x1ZdIGit0wP4ULhgKisCgYARJs3BLps0BD5 + 13 V2eawG  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								cvrZnzuUv8gM6FncrBjjKo + YKlI91R54vsGNx3zr05tyfAixFqKlC4 / 2 PIuL4vFT  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								zK99uRO / Uh8cuAT73uNz1RjrFiDFwANDTSjhiKSoZr + bZiSvPaLFuGzV7zJzUi8s  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								mFC6iQDXayLjbd00BbjyUQKBgHJD2R74sj + ywhFRR8S0brDXn5mx7LYKRfnoCvTe  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								uu6iZw2KFhfdwhibBF7UeF / c048 + ItcbjTUqj4Y3PjZ / usHymMSvprSmLOnLUPd3  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								6 fjufsdMHN5gV2ybZYRuHEtC / LX4o //ccGB+T964smXqxiB81ePViuhC1xd4fsi0
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								svZNAoGBALJOOR8ebtgATqc6jpnFxdqNmlwzAf / dH / jMZ6FZrttqIWiwxKvWaWPK  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								eHJtMmEPMustw / sv1GhDzwWmvgNFPzwEitPKW31m4EdbUCZFxPZ69 / BtHTjXD3q3  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								dP9W + omFXKQ36bVCB6xKmZH / ZVH5iQW0pdkD2JRnUPsDMNBeqmd6  
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:30:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								-- -- - END  RSA  PRIVATE  KEY -- -- - ` )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Starts the test server and returns the TestServer with TLS configured instance.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  StartTestTLSServer ( t  TestErrHandler ,  instanceType  string ,  cert ,  key  [ ] byte )  TestServer  {  
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:30:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Fetch TLS key and pem files from test-data/ directory.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//	dir, _ := os.Getwd()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//	testDataDir := filepath.Join(filepath.Dir(dir), "test-data")
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//	pemFile := filepath.Join(testDataDir, "server.pem")
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//	keyFile := filepath.Join(testDataDir, "server.key")
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cer ,  err  :=  tls . X509KeyPair ( cert ,  key ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 17:30:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Failed to load certificate: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									config  :=  & tls . Config { Certificates :  [ ] tls . Certificate { cer } } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testServer  :=  UnstartedTestServer ( t ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testServer . Server . TLS  =  config 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testServer . Server . StartTLS ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  testServer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Starts the test server and returns the TestServer instance.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  StartTestServer ( t  TestErrHandler ,  instanceType  string )  TestServer  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create an instance of TestServer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testServer  :=  UnstartedTestServer ( t ,  instanceType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testServer . Server . Start ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  testServer 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 17:30:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Initializes storage RPC endpoints.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The object Layer will be a temp back used for testing purpose.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  initTestStorageRPCEndPoint ( srvCmdConfig  serverCmdConfig )  http . Handler  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Initialize router.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									muxRouter  :=  router . NewRouter ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									registerStorageRPCRouters ( muxRouter ,  srvCmdConfig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  muxRouter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// StartTestStorageRPCServer - Creates a temp XL backend and initializes storage RPC end points,
  
						 
					
						
							
								
									
										
										
										
											2016-10-06 17:30:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// then starts a test server with those storage RPC end points registered.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  StartTestStorageRPCServer ( t  TestErrHandler ,  instanceType  string ,  diskN  int )  TestServer  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create temporary backend for the test server.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									disks ,  err  :=  getRandomDisks ( diskN ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Failed to create disks for the backend" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									endpoints ,  err  :=  parseStorageEndpoints ( disks ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-19 03:49:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 17:30:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									root ,  err  :=  newTestConfig ( globalMinioDefaultRegion ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 17:30:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Create an instance of TestServer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer  :=  TestServer { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get credential.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									credentials  :=  serverConfig . GetCredential ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . Root  =  root 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testRPCServer . Disks  =  endpoints 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testRPCServer . AccessKey  =  credentials . AccessKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . SecretKey  =  credentials . SecretKey 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 17:30:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Run TestServer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . Server  =  httptest . NewServer ( initTestStorageRPCEndPoint ( serverCmdConfig { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										endpoints :  endpoints , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 17:30:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  testRPCServer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 16:03:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Sets up a Peers RPC test server.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  StartTestPeersRPCServer ( t  TestErrHandler ,  instanceType  string )  TestServer  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create temporary backend for the test server.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nDisks  :=  16 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									disks ,  err  :=  getRandomDisks ( nDisks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Failed to create disks for the backend" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									endpoints ,  err  :=  parseStorageEndpoints ( disks ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-19 03:49:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 16:03:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									root ,  err  :=  newTestConfig ( globalMinioDefaultRegion ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 16:03:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create an instance of TestServer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer  :=  TestServer { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get credential.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									credentials  :=  serverConfig . GetCredential ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . Root  =  root 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testRPCServer . Disks  =  endpoints 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testRPCServer . AccessKey  =  credentials . AccessKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . SecretKey  =  credentials . SecretKey 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 16:03:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// create temporary backend for the test server.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  _ ,  err  :=  initObjectLayer ( endpoints ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 16:03:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Failed obtaining Temp Backend: <ERROR> %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalObjLayerMutex . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalObjectAPI  =  objLayer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . Obj  =  objLayer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalObjLayerMutex . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									srvCfg  :=  serverCmdConfig { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										endpoints :  endpoints , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 16:03:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mux  :=  router . NewRouter ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// need storage layer for bucket config storage.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									registerStorageRPCRouters ( mux ,  srvCfg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// need API layer to send requests, etc.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									registerAPIRouter ( mux ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// module being tested is Peer RPCs router.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									registerS3PeerRPCRouter ( mux ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Run TestServer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . Server  =  httptest . NewServer ( mux ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// initialize remainder of serverCmdConfig
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . SrvCmdCfg  =  srvCfg 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  testRPCServer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 03:51:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Sets the global config path to empty string.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  resetGlobalConfigPath ( )  {  
						 
					
						
							
								
									
										
										
										
											2017-03-03 06:21:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									setConfigDir ( "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 03:51:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// sets globalObjectAPI to `nil`.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  resetGlobalObjectAPI ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalObjLayerMutex . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalObjectAPI  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalObjLayerMutex . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// reset the value of the Global server config.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// set it to `nil`.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  resetGlobalConfig ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// hold the mutex lock before a new config is assigned.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									serverConfigMu . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Save the loaded config globally.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									serverConfig  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									serverConfigMu . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-08 03:27:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// reset global NSLock.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  resetGlobalNSLock ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  globalNSMutex  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalNSMutex  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// reset global event notifier.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  resetGlobalEventNotifier ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalEventNotifier  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// reset Global event notifier.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  resetGlobalEventnotify ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalEventNotifier  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-23 16:32:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  resetGlobalEndpoints ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalEndpoints  =  [ ] * url . URL { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  resetGlobalIsXL ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalIsXL  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 04:51:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  resetGlobalIsEnvs ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalIsEnvCreds  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 03:51:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Resets all the globals used modified in tests.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Resetting ensures that the changes made to globals by one test doesn't affect others.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  resetTestGlobals ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set globalObjectAPI to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Reset config path set.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalConfigPath ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Reset Global server config.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalConfig ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-08 03:27:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Reset global NSLock.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalNSLock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Reset global event notifier.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalEventnotify ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-23 16:32:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Reset global endpoints.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalEndpoints ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Reset global isXL flag.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalIsXL ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 04:51:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Reset global isEnvCreds flag.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalIsEnvs ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 03:51:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Configure the server for the test run.
  
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  newTestConfig ( bucketLocation  string )  ( rootPath  string ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get test root.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rootPath ,  err  =  getTestRoot ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  "" ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Do this only once here.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-03 06:21:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									setConfigDir ( rootPath ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Initialize server config.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-31 02:21:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  newConfig ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  "" ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set a default region.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									serverConfig . SetRegion ( bucketLocation ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Save config.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  serverConfig . Save ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Return root path.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rootPath ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Deleting the temporary backend and stopping the server.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( testServer  TestServer )  Stop ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									removeAll ( testServer . Root ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  disk  :=  range  testServer . Disks  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										removeAll ( disk . Path ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testServer . Server . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Truncate request to simulate unexpected EOF for a request signed using streaming signature v4.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  truncateChunkByHalfSigv4 ( req  * http . Request )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bufReader  :=  bufio . NewReader ( req . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hexChunkSize ,  chunkSignature ,  err  :=  readChunkLine ( bufReader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newChunkHdr  :=  [ ] byte ( fmt . Sprintf ( "%s" + s3ChunkSignatureStr + "%s\r\n" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hexChunkSize ,  chunkSignature ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newChunk ,  err  :=  ioutil . ReadAll ( bufReader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newReq  :=  req 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newReq . Body  =  ioutil . NopCloser ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bytes . NewReader ( bytes . Join ( [ ] [ ] byte { newChunkHdr ,  newChunk [ : len ( newChunk ) / 2 ] } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											[ ] byte ( "" ) ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  newReq ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Malform data given a request signed using streaming signature V4.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  malformDataSigV4 ( req  * http . Request ,  newByte  byte )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bufReader  :=  bufio . NewReader ( req . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hexChunkSize ,  chunkSignature ,  err  :=  readChunkLine ( bufReader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newChunkHdr  :=  [ ] byte ( fmt . Sprintf ( "%s" + s3ChunkSignatureStr + "%s\r\n" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hexChunkSize ,  chunkSignature ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newChunk ,  err  :=  ioutil . ReadAll ( bufReader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newChunk [ 0 ]  =  newByte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newReq  :=  req 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newReq . Body  =  ioutil . NopCloser ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bytes . NewReader ( bytes . Join ( [ ] [ ] byte { newChunkHdr ,  newChunk } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											[ ] byte ( "" ) ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  newReq ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Malform chunk size given a request signed using streaming signatureV4.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  malformChunkSizeSigV4 ( req  * http . Request ,  badSize  int64 )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bufReader  :=  bufio . NewReader ( req . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_ ,  chunkSignature ,  err  :=  readChunkLine ( bufReader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n  :=  badSize 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newHexChunkSize  :=  [ ] byte ( fmt . Sprintf ( "%x" ,  n ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newChunkHdr  :=  [ ] byte ( fmt . Sprintf ( "%s" + s3ChunkSignatureStr + "%s\r\n" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newHexChunkSize ,  chunkSignature ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newChunk ,  err  :=  ioutil . ReadAll ( bufReader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newReq  :=  req 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newReq . Body  =  ioutil . NopCloser ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bytes . NewReader ( bytes . Join ( [ ] [ ] byte { newChunkHdr ,  newChunk } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											[ ] byte ( "" ) ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  newReq ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Sign given request using Signature V4.
  
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  signStreamingRequest ( req  * http . Request ,  accessKey ,  secretKey  string ,  currTime  time . Time )  ( string ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Get hashed payload.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hashedPayload  :=  req . Header . Get ( "x-amz-content-sha256" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  hashedPayload  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-16 10:14:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  "" ,  fmt . Errorf ( "Invalid hashed payload" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set x-amz-date.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "x-amz-date" ,  currTime . Format ( iso8601Format ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get header map.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									headerMap  :=  make ( map [ string ] [ ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  k ,  vv  :=  range  req . Header  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// If request header key is not in ignored headers, then add it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  ok  :=  ignoredStreamingHeaders [ http . CanonicalHeaderKey ( k ) ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											headerMap [ strings . ToLower ( k ) ]  =  vv 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get header keys.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									headers  :=  [ ] string { "host" } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  k  :=  range  headerMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										headers  =  append ( headers ,  k ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sort . Strings ( headers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get canonical headers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  buf  bytes . Buffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  k  :=  range  headers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteString ( k ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteByte ( ':' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  k  ==  "host" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buf . WriteString ( req . URL . Host ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fallthrough 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  idx ,  v  :=  range  headerMap [ k ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  idx  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													buf . WriteByte ( ',' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												buf . WriteString ( v ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											buf . WriteByte ( '\n' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									canonicalHeaders  :=  buf . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get signed headers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signedHeaders  :=  strings . Join ( headers ,  ";" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get canonical query string.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . URL . RawQuery  =  strings . Replace ( req . URL . Query ( ) . Encode ( ) ,  "+" ,  "%20" ,  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get canonical URI.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									canonicalURI  :=  getURLEncodedName ( req . URL . Path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get canonical request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// canonicalRequest =
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <HTTPMethod>\n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <CanonicalURI>\n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <CanonicalQueryString>\n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <CanonicalHeaders>\n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <SignedHeaders>\n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <HashedPayload>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									canonicalRequest  :=  strings . Join ( [ ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Method , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										canonicalURI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . URL . RawQuery , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										canonicalHeaders , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										signedHeaders , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hashedPayload , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ,  "\n" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get scope.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									scope  :=  strings . Join ( [ ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										currTime . Format ( yyyymmdd ) , 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalMinioDefaultRegion , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"s3" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"aws4_request" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ,  "/" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									stringToSign  :=  "AWS4-HMAC-SHA256"  +  "\n"  +  currTime . Format ( iso8601Format )  +  "\n" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									stringToSign  =  stringToSign  +  scope  +  "\n" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-22 05:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stringToSign  =  stringToSign  +  getSHA256Hash ( [ ] byte ( canonicalRequest ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									date  :=  sumHMAC ( [ ] byte ( "AWS4" + secretKey ) ,  [ ] byte ( currTime . Format ( yyyymmdd ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									region  :=  sumHMAC ( date ,  [ ] byte ( globalMinioDefaultRegion ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									service  :=  sumHMAC ( region ,  [ ] byte ( "s3" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signingKey  :=  sumHMAC ( service ,  [ ] byte ( "aws4_request" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signature  :=  hex . EncodeToString ( sumHMAC ( signingKey ,  [ ] byte ( stringToSign ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// final Authorization header
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parts  :=  [ ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"AWS4-HMAC-SHA256"  +  " Credential="  +  accessKey  +  "/"  +  scope , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"SignedHeaders="  +  signedHeaders , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"Signature="  +  signature , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									auth  :=  strings . Join ( parts ,  ", " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "Authorization" ,  auth ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  signature ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Returns new HTTP request object.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  newTestStreamingRequest ( method ,  urlStr  string ,  dataLength ,  chunkSize  int64 ,  body  io . ReadSeeker )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  method  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										method  =  "POST" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  http . NewRequest ( method ,  urlStr ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  body  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// this is added to avoid panic during ioutil.ReadAll(req.Body).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// th stack trace can be found here  https://github.com/minio/minio/pull/2074 .
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This is very similar to https://github.com/golang/go/issues/7527.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Body  =  ioutil . NopCloser ( bytes . NewReader ( [ ] byte ( "" ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									contentLength  :=  calculateStreamContentLength ( dataLength ,  chunkSize ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "x-amz-content-sha256" ,  "STREAMING-AWS4-HMAC-SHA256-PAYLOAD" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "content-encoding" ,  "aws-chunked" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "x-amz-decoded-content-length" ,  strconv . FormatInt ( dataLength ,  10 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "content-length" ,  strconv . FormatInt ( contentLength ,  10 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Seek back to beginning.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									body . Seek ( 0 ,  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Add body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Body  =  ioutil . NopCloser ( body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . ContentLength  =  contentLength 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  req ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  assembleStreamingChunks ( req  * http . Request ,  body  io . ReadSeeker ,  chunkSize  int64 ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									secretKey ,  signature  string ,  currTime  time . Time )  ( * http . Request ,  error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									regionStr  :=  serverConfig . GetRegion ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  stream  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  buffer  [ ] byte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									body . Seek ( 0 ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buffer  =  make ( [ ] byte ,  chunkSize ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n ,  err  :=  body . Read ( buffer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  &&  err  !=  io . EOF  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Get scope.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										scope  :=  strings . Join ( [ ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											currTime . Format ( yyyymmdd ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											regionStr , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											"s3" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"aws4_request" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ,  "/" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stringToSign  :=  "AWS4-HMAC-SHA256-PAYLOAD"  +  "\n" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stringToSign  =  stringToSign  +  currTime . Format ( iso8601Format )  +  "\n" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stringToSign  =  stringToSign  +  scope  +  "\n" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stringToSign  =  stringToSign  +  signature  +  "\n" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stringToSign  =  stringToSign  +  "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"  +  "\n"  // hex(sum256(""))
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-22 05:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										stringToSign  =  stringToSign  +  getSHA256Hash ( buffer [ : n ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										date  :=  sumHMAC ( [ ] byte ( "AWS4" + secretKey ) ,  [ ] byte ( currTime . Format ( yyyymmdd ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-16 17:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										region  :=  sumHMAC ( date ,  [ ] byte ( regionStr ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										service  :=  sumHMAC ( region ,  [ ] byte ( "s3" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										signingKey  :=  sumHMAC ( service ,  [ ] byte ( "aws4_request" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										signature  =  hex . EncodeToString ( sumHMAC ( signingKey ,  [ ] byte ( stringToSign ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stream  =  append ( stream ,  [ ] byte ( fmt . Sprintf ( "%x" ,  n ) + ";chunk-signature=" + signature + "\r\n" ) ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stream  =  append ( stream ,  buffer [ : n ] ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										stream  =  append ( stream ,  [ ] byte ( "\r\n" ) ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  n  <=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Body  =  ioutil . NopCloser ( bytes . NewReader ( stream ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  req ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newTestStreamingSignedBadChunkDateRequest ( method ,  urlStr  string ,  contentLength ,  chunkSize  int64 ,  body  io . ReadSeeker ,  accessKey ,  secretKey  string )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  newTestStreamingRequest ( method ,  urlStr ,  contentLength ,  chunkSize ,  body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 02:28:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									currTime  :=  UTCNow ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									signature ,  err  :=  signStreamingRequest ( req ,  accessKey ,  secretKey ,  currTime ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// skew the time between the chunk signature calculation and seed signature.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									currTime  =  currTime . Add ( 1  *  time . Second ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  =  assembleStreamingChunks ( req ,  body ,  chunkSize ,  secretKey ,  signature ,  currTime ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-31 14:32:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  req ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-28 08:02:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newTestStreamingSignedCustomEncodingRequest ( method ,  urlStr  string ,  contentLength ,  chunkSize  int64 ,  body  io . ReadSeeker ,  accessKey ,  secretKey ,  contentEncoding  string )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  newTestStreamingRequest ( method ,  urlStr ,  contentLength ,  chunkSize ,  body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set custom encoding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "content-encoding" ,  contentEncoding ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									currTime  :=  UTCNow ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signature ,  err  :=  signStreamingRequest ( req ,  accessKey ,  secretKey ,  currTime ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  =  assembleStreamingChunks ( req ,  body ,  chunkSize ,  secretKey ,  signature ,  currTime ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  req ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Returns new HTTP request object signed with streaming signature v4.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  newTestStreamingSignedRequest ( method ,  urlStr  string ,  contentLength ,  chunkSize  int64 ,  body  io . ReadSeeker ,  accessKey ,  secretKey  string )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  newTestStreamingRequest ( method ,  urlStr ,  contentLength ,  chunkSize ,  body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 02:28:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									currTime  :=  UTCNow ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									signature ,  err  :=  signStreamingRequest ( req ,  accessKey ,  secretKey ,  currTime ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  =  assembleStreamingChunks ( req ,  body ,  chunkSize ,  secretKey ,  signature ,  currTime ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-31 14:32:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  req ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 13:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// preSignV4 presign the request, in accordance with
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  preSignV4 ( req  * http . Request ,  accessKeyID ,  secretAccessKey  string ,  expires  int64 )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Presign is not needed for anonymous credentials.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  accessKeyID  ==  ""  ||  secretAccessKey  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errors . New ( "Presign cannot be generated without access and secret keys" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									region  :=  serverConfig . GetRegion ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 02:28:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									date  :=  UTCNow ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 05:09:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									scope  :=  getScope ( date ,  region ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									credential  :=  fmt . Sprintf ( "%s/%s" ,  accessKeyID ,  scope ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 13:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set URL query.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query  :=  req . URL . Query ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( "X-Amz-Algorithm" ,  signV4Algorithm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( "X-Amz-Date" ,  date . Format ( iso8601Format ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( "X-Amz-Expires" ,  strconv . FormatInt ( expires ,  10 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( "X-Amz-SignedHeaders" ,  "host" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( "X-Amz-Credential" ,  credential ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( "X-Amz-Content-Sha256" ,  unsignedPayload ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Headers are empty, since "host" is the only header required to be signed for Presigned URLs.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  extractedSignedHeaders  http . Header 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryStr  :=  strings . Replace ( query . Encode ( ) ,  "+" ,  "%20" ,  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									canonicalRequest  :=  getCanonicalRequest ( extractedSignedHeaders ,  unsignedPayload ,  queryStr ,  req . URL . Path ,  req . Method ,  req . Host ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 05:09:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stringToSign  :=  getStringToSign ( canonicalRequest ,  date ,  scope ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 13:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									signingKey  :=  getSigningKey ( secretAccessKey ,  date ,  region ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signature  :=  getSignature ( signingKey ,  stringToSign ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . URL . RawQuery  =  query . Encode ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Add signature header to RawQuery.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:56:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req . URL . RawQuery  +=  "&X-Amz-Signature="  +  url . QueryEscape ( signature ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 13:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Construct the final presigned URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// preSignV2 - presign the request in following style.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// https://${S3_BUCKET}.s3.amazonaws.com/${S3_OBJECT}?AWSAccessKeyId=${S3_ACCESS_KEY}&Expires=${TIMESTAMP}&Signature=${SIGNATURE}.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  preSignV2 ( req  * http . Request ,  accessKeyID ,  secretAccessKey  string ,  expires  int64 )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Presign is not needed for anonymous credentials.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  accessKeyID  ==  ""  ||  secretAccessKey  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errors . New ( "Presign cannot be generated without access and secret keys" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 02:28:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									d  :=  UTCNow ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Find epoch expires when the request will expire.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									epochExpires  :=  d . Unix ( )  +  expires 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Add expires header if not present.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 00:18:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									expiresStr  :=  req . Header . Get ( "Expires" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  expiresStr  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expiresStr  =  strconv . FormatInt ( epochExpires ,  10 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Header . Set ( "Expires" ,  expiresStr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// url.RawPath will be valid if path has any encoded characters, if not it will
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// be empty - in which case we need to consider url.Path (bug in net/http?)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									encodedResource  :=  req . URL . RawPath 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									encodedQuery  :=  req . URL . RawQuery 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  encodedResource  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										splits  :=  strings . Split ( req . URL . Path ,  "?" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( splits )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											encodedResource  =  splits [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get presigned string to sign.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 00:18:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stringToSign  :=  presignV2STS ( req . Method ,  encodedResource ,  encodedQuery ,  req . Header ,  expiresStr ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hm  :=  hmac . New ( sha1 . New ,  [ ] byte ( secretAccessKey ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hm . Write ( [ ] byte ( stringToSign ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Calculate signature.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signature  :=  base64 . StdEncoding . EncodeToString ( hm . Sum ( nil ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query  :=  req . URL . Query ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Handle specially for Google Cloud Storage.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( "AWSAccessKeyId" ,  accessKeyID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Fill in Expires for presigned query.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( "Expires" ,  strconv . FormatInt ( epochExpires ,  10 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Encode query and save.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:56:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req . URL . RawQuery  =  query . Encode ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Save signature finally.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:56:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req . URL . RawQuery  +=  "&Signature="  +  url . QueryEscape ( signature ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Success.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Sign given request using Signature V2.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  signRequestV2 ( req  * http . Request ,  accessKey ,  secretKey  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Initial time.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 02:28:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									d  :=  UTCNow ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Add date if not present.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  date  :=  req . Header . Get ( "Date" ) ;  date  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Header . Set ( "Date" ,  d . Format ( http . TimeFormat ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 00:18:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// url.RawPath will be valid if path has any encoded characters, if not it will
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// be empty - in which case we need to consider url.Path (bug in net/http?)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									encodedResource  :=  req . URL . RawPath 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  encodedResource  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										splits  :=  strings . Split ( req . URL . Path ,  "?" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( splits )  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-15 02:23:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											encodedResource  =  getURLEncodedName ( splits [ 0 ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 00:18:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-15 02:23:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									encodedQuery  :=  req . URL . Query ( ) . Encode ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 00:18:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Calculate HMAC for secretAccessKey.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 00:18:53 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stringToSign  :=  signV2STS ( req . Method ,  encodedResource ,  encodedQuery ,  req . Header ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hm  :=  hmac . New ( sha1 . New ,  [ ] byte ( secretKey ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hm . Write ( [ ] byte ( stringToSign ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Prepare auth header.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									authHeader  :=  new ( bytes . Buffer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									authHeader . WriteString ( fmt . Sprintf ( "%s %s:" ,  signV2Algorithm ,  accessKey ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									encoder  :=  base64 . NewEncoder ( base64 . StdEncoding ,  authHeader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									encoder . Write ( hm . Sum ( nil ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									encoder . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set Authorization header.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "Authorization" ,  authHeader . String ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Sign given request using Signature V4.
  
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  signRequestV4 ( req  * http . Request ,  accessKey ,  secretKey  string )  error  {  
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Get hashed payload.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hashedPayload  :=  req . Header . Get ( "x-amz-content-sha256" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  hashedPayload  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-16 10:14:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  fmt . Errorf ( "Invalid hashed payload" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 02:28:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									currTime  :=  UTCNow ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Set x-amz-date.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "x-amz-date" ,  currTime . Format ( iso8601Format ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Get header map.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									headerMap  :=  make ( map [ string ] [ ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  k ,  vv  :=  range  req . Header  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// If request header key is not in ignored headers, then add it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  ok  :=  ignoredHeaders [ http . CanonicalHeaderKey ( k ) ] ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											headerMap [ strings . ToLower ( k ) ]  =  vv 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Get header keys.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									headers  :=  [ ] string { "host" } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  k  :=  range  headerMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										headers  =  append ( headers ,  k ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sort . Strings ( headers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 14:53:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									region  :=  serverConfig . GetRegion ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Get canonical headers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  buf  bytes . Buffer 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  _ ,  k  :=  range  headers  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										buf . WriteString ( k ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										buf . WriteByte ( ':' ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  k  ==  "host" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											buf . WriteString ( req . URL . Host ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											fallthrough 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											for  idx ,  v  :=  range  headerMap [ k ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  idx  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													buf . WriteByte ( ',' ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												buf . WriteString ( v ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											buf . WriteByte ( '\n' ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									canonicalHeaders  :=  buf . String ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Get signed headers.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									signedHeaders  :=  strings . Join ( headers ,  ";" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Get canonical query string.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									req . URL . RawQuery  =  strings . Replace ( req . URL . Query ( ) . Encode ( ) ,  "+" ,  "%20" ,  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Get canonical URI.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									canonicalURI  :=  getURLEncodedName ( req . URL . Path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get canonical request.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// canonicalRequest =
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <HTTPMethod>\n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <CanonicalURI>\n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <CanonicalQueryString>\n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <CanonicalHeaders>\n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <SignedHeaders>\n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  <HashedPayload>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									canonicalRequest  :=  strings . Join ( [ ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Method , 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										canonicalURI , 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										req . URL . RawQuery , 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										canonicalHeaders , 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										signedHeaders , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hashedPayload , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ,  "\n" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Get scope.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									scope  :=  strings . Join ( [ ] string { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										currTime . Format ( yyyymmdd ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 14:53:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										region , 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										"s3" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"aws4_request" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ,  "/" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									stringToSign  :=  "AWS4-HMAC-SHA256"  +  "\n"  +  currTime . Format ( iso8601Format )  +  "\n" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									stringToSign  =  stringToSign  +  scope  +  "\n" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-22 05:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stringToSign  =  stringToSign  +  getSHA256Hash ( [ ] byte ( canonicalRequest ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									date  :=  sumHMAC ( [ ] byte ( "AWS4" + secretKey ) ,  [ ] byte ( currTime . Format ( yyyymmdd ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 14:53:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									regionHMAC  :=  sumHMAC ( date ,  [ ] byte ( region ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									service  :=  sumHMAC ( regionHMAC ,  [ ] byte ( "s3" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									signingKey  :=  sumHMAC ( service ,  [ ] byte ( "aws4_request" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signature  :=  hex . EncodeToString ( sumHMAC ( signingKey ,  [ ] byte ( stringToSign ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// final Authorization header
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parts  :=  [ ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"AWS4-HMAC-SHA256"  +  " Credential="  +  accessKey  +  "/"  +  scope , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"SignedHeaders="  +  signedHeaders , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"Signature="  +  signature , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									auth  :=  strings . Join ( parts ,  ", " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "Authorization" ,  auth ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// getCredentialString generate a credential string.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getCredentialString ( accessKeyID ,  location  string ,  t  time . Time )  string  {  
						 
					
						
							
								
									
										
										
										
											2016-09-14 10:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  accessKeyID  +  "/"  +  getScope ( t ,  location ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Returns new HTTP request object.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  newTestRequest ( method ,  urlStr  string ,  contentLength  int64 ,  body  io . ReadSeeker )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  method  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										method  =  "POST" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  http . NewRequest ( method ,  urlStr ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Add Content-Length
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . ContentLength  =  contentLength 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Save for subsequent use
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  hashedPayload  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  body  ==  nil : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-22 05:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hashedPayload  =  getSHA256Hash ( [ ] byte { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										payloadBytes ,  err  :=  ioutil . ReadAll ( body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-22 05:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hashedPayload  =  getSHA256Hash ( payloadBytes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										md5Base64  :=  getMD5HashBase64 ( payloadBytes ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										req . Header . Set ( "Content-Md5" ,  md5Base64 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "x-amz-content-sha256" ,  hashedPayload ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Seek back to beginning.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  body  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										body . Seek ( 0 ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Add body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Body  =  ioutil . NopCloser ( body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// this is added to avoid panic during ioutil.ReadAll(req.Body).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// th stack trace can be found here  https://github.com/minio/minio/pull/2074 .
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This is very similar to https://github.com/golang/go/issues/7527.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Body  =  ioutil . NopCloser ( bytes . NewReader ( [ ] byte ( "" ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  req ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 04:34:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Various signature types we are supporting, currently
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// two main signature types.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  signerType  int  
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 04:34:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signerV2  signerType  =  iota 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signerV4 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 04:34:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newTestSignedRequest ( method ,  urlStr  string ,  contentLength  int64 ,  body  io . ReadSeeker ,  accessKey ,  secretKey  string ,  signer  signerType )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  signer  ==  signerV2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  newTestSignedRequestV2 ( method ,  urlStr ,  contentLength ,  body ,  accessKey ,  secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-26 04:34:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  newTestSignedRequestV4 ( method ,  urlStr ,  contentLength ,  body ,  accessKey ,  secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Returns new HTTP request object signed with signature v2.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  newTestSignedRequestV2 ( method ,  urlStr  string ,  contentLength  int64 ,  body  io . ReadSeeker ,  accessKey ,  secretKey  string )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  newTestRequest ( method ,  urlStr ,  contentLength ,  body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Del ( "x-amz-content-sha256" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Anonymous request return quickly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  accessKey  ==  ""  ||  secretKey  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  req ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  signRequestV2 ( req ,  accessKey ,  secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  req ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Returns new HTTP request object signed with signature v4.
  
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newTestSignedRequestV4 ( method ,  urlStr  string ,  contentLength  int64 ,  body  io . ReadSeeker ,  accessKey ,  secretKey  string )  ( * http . Request ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  newTestRequest ( method ,  urlStr ,  contentLength ,  body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-10 01:18:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Anonymous request return quickly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  accessKey  ==  ""  ||  secretKey  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  req ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  signRequestV4 ( req ,  accessKey ,  secretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  req ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-16 07:13:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Return new WebRPC request object.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  newWebRPCRequest ( methodRPC ,  authorization  string ,  body  io . ReadSeeker )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  http . NewRequest ( "POST" ,  "/minio/webrpc" ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "Content-Type" ,  "application/json" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authorization  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Header . Set ( "Authorization" ,  "Bearer " + authorization ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Seek back to beginning.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  body  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										body . Seek ( 0 ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Add body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Body  =  ioutil . NopCloser ( body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// this is added to avoid panic during ioutil.ReadAll(req.Body).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// th stack trace can be found here  https://github.com/minio/minio/pull/2074 .
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This is very similar to https://github.com/golang/go/issues/7527.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Body  =  ioutil . NopCloser ( bytes . NewReader ( [ ] byte ( "" ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  req ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Marshal request and return a new HTTP request object to call the webrpc
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  newTestWebRPCRequest ( rpcMethod  string ,  authorization  string ,  data  interface { } )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  genericJSON  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										JSONRPC  string       ` json:"jsonrpc" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ID       string       ` json:"id" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Method   string       ` json:"method" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Params   interface { }  ` json:"params" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									encapsulatedData  :=  genericJSON { JSONRPC :  "2.0" ,  ID :  "1" ,  Method :  rpcMethod ,  Params :  data } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									jsonData ,  err  :=  json . Marshal ( encapsulatedData ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-02 14:10:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-16 07:13:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  newWebRPCRequest ( rpcMethod ,  authorization ,  bytes . NewReader ( jsonData ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  req ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  ErrWebRPC  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Code     int          ` json:"code" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Message  string       ` json:"message" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Data     interface { }  ` json:"data" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Unmarshal response and return the webrpc response
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getTestWebRPCResponse ( resp  * httptest . ResponseRecorder ,  data  interface { } )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  rpcReply  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ID       string       ` json:"id" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										JSONRPC  string       ` json:"jsonrpc" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Result   interface { }  ` json:"result" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Error    * ErrWebRPC   ` json:"error" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply  :=  & rpcReply { Result :  & data } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  :=  json . NewDecoder ( resp . Body ) . Decode ( reply ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// For the moment, web handlers errors code are not meaningful
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Return only the error message
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  reply . Error  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errors . New ( reply . Error . Message ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 02:28:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  src  =  rand . NewSource ( UTCNow ( ) . UnixNano ( ) )  
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Function to generate random string for bucket/object names.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  randString ( n  int )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									b  :=  make ( [ ] byte ,  n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// A rand.Int63() generates 63 random bits, enough for letterIdxMax letters!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i ,  cache ,  remain  :=  n - 1 ,  src . Int63 ( ) ,  letterIdxMax ;  i  >=  0 ;  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  remain  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cache ,  remain  =  src . Int63 ( ) ,  letterIdxMax 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  idx  :=  int ( cache  &  letterIdxMask ) ;  idx  <  len ( letterBytes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											b [ i ]  =  letterBytes [ idx ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											i -- 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cache  >>=  letterIdxBits 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										remain -- 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  string ( b ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-09 05:28:06 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// generate random object name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getRandomObjectName ( )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  randString ( 16 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// generate random bucket name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getRandomBucketName ( )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  randString ( 60 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-31 04:36:43 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// TruncateWriter - Writes `n` bytes, then returns with number of bytes written.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// differs from iotest.TruncateWriter, the difference is commented in the Write method.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TruncateWriter ( w  io . Writer ,  n  int64 )  io . Writer  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & truncateWriter { w ,  n } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  truncateWriter  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w  io . Writer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( t  * truncateWriter )  Write ( p  [ ] byte )  ( n  int ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  t . n  <=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  len ( p ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// real write
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n  =  len ( p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  int64 ( n )  >  t . n  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n  =  int ( t . n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n ,  err  =  t . w . Write ( p [ 0 : n ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . n  -=  int64 ( n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Removed from iotest.TruncateWriter.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Need the Write method to return truncated number of bytes written, not the size of the buffer requested to be written.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// if err == nil {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 	n = len(p)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-09 09:26:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// NewEOFWriter returns a Writer that writes to w,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but returns EOF error after writing n bytes.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NewEOFWriter ( w  io . Writer ,  n  int64 )  io . Writer  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & EOFWriter { w ,  n } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  EOFWriter  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w  io . Writer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-10 08:11:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// io.Writer implementation designed to error out with io.EOF after reading `n` bytes.
  
						 
					
						
							
								
									
										
										
										
											2016-07-09 09:26:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( t  * EOFWriter )  Write ( p  [ ] byte )  ( n  int ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  t . n  <=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ,  io . EOF 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// real write
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n  =  len ( p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  int64 ( n )  >  t . n  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n  =  int ( t . n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n ,  err  =  t . w . Write ( p [ 0 : n ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t . n  -=  int64 ( n ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n  =  len ( p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// construct URL for http requests for bucket operations.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  makeTestTargetURL ( endPoint ,  bucketName ,  objectName  string ,  queryValues  url . Values )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									urlStr  :=  endPoint  +  "/" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  bucketName  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										urlStr  =  urlStr  +  bucketName  +  "/" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectName  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										urlStr  =  urlStr  +  getURLEncodedName ( objectName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( queryValues )  >  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-27 02:56:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										urlStr  =  urlStr  +  "?"  +  queryValues . Encode ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  urlStr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for uploading object into the bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getPutObjectURL ( endPoint ,  bucketName ,  objectName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  url . Values { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getPutObjectPartURL ( endPoint ,  bucketName ,  objectName ,  uploadID ,  partNumber  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValues  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValues . Set ( "uploadId" ,  uploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValues . Set ( "partNumber" ,  partNumber ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  queryValues ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getCopyObjectPartURL ( endPoint ,  bucketName ,  objectName ,  uploadID ,  partNumber  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValues  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValues . Set ( "uploadId" ,  uploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValues . Set ( "partNumber" ,  partNumber ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  queryValues ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// return URL for fetching object from the bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getGetObjectURL ( endPoint ,  bucketName ,  objectName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  url . Values { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for deleting the object from the bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getDeleteObjectURL ( endPoint ,  bucketName ,  objectName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  url . Values { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-02 16:59:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return URL for deleting multiple objects from a bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getMultiDeleteObjectURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "delete" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 08:41:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-02 16:59:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// return URL for HEAD on the object.
  
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  getHeadObjectURL ( endPoint ,  bucketName ,  objectName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  url . Values { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// return url to be used while copying the object.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getCopyObjectURL ( endPoint ,  bucketName ,  objectName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  url . Values { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-05 13:01:58 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// return URL for inserting bucket notification.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getPutNotificationURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "notification" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for fetching bucket notification.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getGetNotificationURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "notification" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// return URL for inserting bucket policy.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getPutPolicyURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "policy" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for fetching bucket policy.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getGetPolicyURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "policy" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for deleting bucket policy.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getDeletePolicyURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
									
										
										
										
											2016-07-04 13:35:30 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "policy" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for creating the bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getMakeBucketURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  url . Values { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for listing buckets.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getListBucketURL ( endPoint  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  "" ,  "" ,  url . Values { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for HEAD on the bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getHEADBucketURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  url . Values { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for deleting the bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getDeleteBucketURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  url . Values { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-10 01:18:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-17 01:46:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return URL for deleting the bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getDeleteMultipleObjectsURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "delete" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-10 01:18:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return URL For fetching location of the bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getBucketLocationURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "location" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 03:32:05 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// return URL for listing objects in the bucket with V1 legacy API.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getListObjectsV1URL ( endPoint ,  bucketName  string ,  maxKeys  string )  string  {  
						 
					
						
							
								
									
										
										
										
											2016-06-28 14:54:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  maxKeys  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queryValue . Set ( "max-keys" ,  maxKeys ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 03:32:05 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// return URL for listing objects in the bucket with V2 API.
  
						 
					
						
							
								
									
										
										
										
											2016-09-11 01:44:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getListObjectsV2URL ( endPoint ,  bucketName  string ,  maxKeys  string ,  fetchOwner  string )  string  {  
						 
					
						
							
								
									
										
										
										
											2016-07-18 03:32:05 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "list-type" ,  "2" )  // Enables list objects V2 URL.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  maxKeys  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queryValue . Set ( "max-keys" ,  maxKeys ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 01:44:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  fetchOwner  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queryValue . Set ( "fetch-owner" ,  fetchOwner ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 03:32:05 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-28 14:54:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// return URL for a new multipart upload.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getNewMultipartURL ( endPoint ,  bucketName ,  objectName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "uploads" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for a new multipart upload.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getPartUploadURL ( endPoint ,  bucketName ,  objectName ,  uploadID ,  partNumber  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValues  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValues . Set ( "uploadId" ,  uploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValues . Set ( "partNumber" ,  partNumber ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  queryValues ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for aborting multipart upload.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getAbortMultipartUploadURL ( endPoint ,  bucketName ,  objectName ,  uploadID  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "uploadId" ,  uploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-14 10:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return URL for a listing pending multipart uploads.
  
						 
					
						
							
								
									
										
										
										
											2016-06-28 14:54:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  getListMultipartURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "uploads" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-14 10:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return URL for listing pending multipart uploads with parameters.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getListMultipartUploadsURLWithParams ( endPoint ,  bucketName ,  prefix ,  keyMarker ,  uploadIDMarker ,  delimiter ,  maxUploads  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "uploads" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "prefix" ,  prefix ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "delimiter" ,  delimiter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "key-marker" ,  keyMarker ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "upload-id-marker" ,  uploadIDMarker ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "max-uploads" ,  maxUploads ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for a listing parts on a given upload id.
  
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getListMultipartURLWithParams ( endPoint ,  bucketName ,  objectName ,  uploadID ,  maxParts ,  partNumberMarker ,  encoding  string )  string  {  
						 
					
						
							
								
									
										
										
										
											2016-06-28 14:54:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									queryValues  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValues . Set ( "uploadId" ,  uploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValues . Set ( "max-parts" ,  maxParts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-03 23:54:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  partNumberMarker  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queryValues . Set ( "part-number-marker" ,  partNumberMarker ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-28 14:54:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  queryValues ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for completing multipart upload.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// complete multipart upload request is sent after all parts are uploaded.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getCompleteMultipartUploadURL ( endPoint ,  bucketName ,  objectName ,  uploadID  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "uploadId" ,  uploadID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  objectName ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-22 08:41:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return URL for put bucket notification.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getPutBucketNotificationURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  getGetBucketNotificationURL ( endPoint ,  bucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return URL for get bucket notification.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getGetBucketNotificationURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "notification" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-28 16:08:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return URL for listen bucket notification.
  
						 
					
						
							
								
									
										
										
										
											2016-10-13 02:02:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getListenBucketNotificationURL ( endPoint ,  bucketName  string ,  prefixes ,  suffixes ,  events  [ ] string )  string  {  
						 
					
						
							
								
									
										
										
										
											2016-09-28 16:08:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-13 02:02:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue [ "prefix" ]  =  prefixes 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue [ "suffix" ]  =  suffixes 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-28 16:08:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									queryValue [ "events" ]  =  events 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// returns temp root directory. `
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getTestRoot ( )  ( string ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-12-16 14:25:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ioutil . TempDir ( globalTestTmpDir ,  "api-" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// getRandomDisks - Creates a slice of N random disks, each of the form - minio-XXX
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getRandomDisks ( N  int )  ( [ ] string ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									var  erasureDisks  [ ] string 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <  N ;  i ++  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 14:25:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										path ,  err  :=  ioutil . TempDir ( globalTestTmpDir ,  "minio-" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Remove directories created so far.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											removeRoots ( erasureDisks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										erasureDisks  =  append ( erasureDisks ,  path ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  erasureDisks ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// initObjectLayer - Instantiates object layer and returns it.
  
						 
					
						
							
								
									
										
										
										
											2016-11-12 08:36:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  initObjectLayer ( endpoints  [ ] * url . URL )  ( ObjectLayer ,  [ ] StorageAPI ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									storageDisks ,  err  :=  initStorageDisks ( endpoints ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									formattedDisks ,  err  :=  waitForFormatXLDisks ( true ,  endpoints ,  storageDisks ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  err  :=  newXLObjectLayer ( formattedDisks ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Disabling the cache for integration tests.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Should use the object layer tests for validating cache.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-17 08:42:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  xl ,  ok  :=  objLayer . ( * xlObjects ) ;  ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 10:24:23 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										xl . objCacheEnabled  =  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Success.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-24 07:48:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  objLayer ,  formattedDisks ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// removeRoots - Cleans up initialized directories during tests.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  removeRoots ( roots  [ ] string )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  root  :=  range  roots  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-13 17:53:09 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										removeAll ( root ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-29 13:32:00 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								//removeDiskN - removes N disks from supplied disk slice.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  removeDiskN ( disks  [ ] string ,  n  int )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  n  >  len ( disks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n  =  len ( disks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  disk  :=  range  disks [ : n ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										removeAll ( disk ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Makes a entire new copy of a StorageAPI slice.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  deepCopyStorageDisks ( storageDisks  [ ] StorageAPI )  [ ] StorageAPI  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newStorageDisks  :=  make ( [ ] StorageAPI ,  len ( storageDisks ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-09 02:00:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									copy ( newStorageDisks ,  storageDisks ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  newStorageDisks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Initializes storage disks with 'N' errored disks, N disks return 'err' for each disk access.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  prepareNErroredDisks ( storageDisks  [ ] StorageAPI ,  offline  int ,  err  error ,  t  * testing . T )  [ ] StorageAPI  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  offline  >  len ( storageDisks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Requested more offline disks than supplied storageDisks slice" ,  offline ,  len ( storageDisks ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <  offline ;  i ++  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-31 09:08:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										storageDisks [ i ]  =  & naughtyDisk { disk :  & retryStorage { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											remoteStorage :     storageDisks [ i ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											maxRetryAttempts :  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											retryUnit :         time . Millisecond , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											retryCap :          time . Millisecond  *  10 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ,  defaultErr :  err } 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  storageDisks 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Initializes storage disks with 'N' offline disks, N disks returns 'errDiskNotFound' for each disk access.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  prepareNOfflineDisks ( storageDisks  [ ] StorageAPI ,  offline  int ,  t  * testing . T )  [ ] StorageAPI  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  prepareNErroredDisks ( storageDisks ,  offline ,  errDiskNotFound ,  t ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Initializes backend storage disks.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  prepareXLStorageDisks ( t  * testing . T )  ( [ ] StorageAPI ,  [ ] string )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nDisks  :=  16 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fsDirs ,  err  :=  getRandomDisks ( nDisks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Unexpected error: " ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									endpoints ,  err  :=  parseStorageEndpoints ( fsDirs ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-19 03:49:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Unexpected error: " ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-12 08:36:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  storageDisks ,  err  :=  initObjectLayer ( endpoints ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										removeRoots ( fsDirs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Unable to initialize storage disks" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  storageDisks ,  fsDirs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// creates a bucket for the tests and returns the bucket name.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// initializes the specified API endpoints for the tests.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// initialies the root and returns its path.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return credentials.
  
						 
					
						
							
								
									
										
										
										
											2017-01-24 09:01:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  initAPIHandlerTest ( obj  ObjectLayer ,  endpoints  [ ] string )  ( string ,  http . Handler ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// get random bucket name.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-24 09:01:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bucketName  :=  getRandomBucketName ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Create bucket.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-24 09:01:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  :=  obj . MakeBucket ( bucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// failed to create newbucket, return err.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-21 16:25:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  "" ,  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Register the API end points with XL object layer.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Registering only the GetObject handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-24 09:01:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									apiRouter  :=  initTestAPIEndPoints ( obj ,  endpoints ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  f  http . HandlerFunc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									f  =  func ( w  http . ResponseWriter ,  r  * http . Request )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . RequestURI  =  r . URL . RequestURI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( w ,  r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  bucketName ,  f ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// prepare test backend.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// create FS/XL bankend.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// return object layer, backend disks.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  prepareTestBackend ( instanceType  string )  ( ObjectLayer ,  [ ] string ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  instanceType  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Total number of disks for XL backend is set to 16.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  XLTestStr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  prepareXL ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// return FS backend by default.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										obj ,  disk ,  err  :=  prepareFS ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  obj ,  [ ] string { disk } ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ExecObjectLayerAPIAnonTest - Helper function to validate object Layer API handler
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// response for anonymous/unsigned and unknown signature type HTTP request.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Here is the brief description of some of the arguments to the function below.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//   apiRouter - http.Handler with the relevant API endPoint (API endPoint under test) registered.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//   anonReq   - unsigned *http.Request to invoke the handler's response for anonymous requests.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//   policyFunc    - function to return bucketPolicy statement which would permit the anonymous request to be served.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The test works in 2 steps, here is the description of the steps.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//   STEP 1: Call the handler with the unsigned HTTP request (anonReq), assert for the `ErrAccessDenied` error response.
  
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//   STEP 2: Set the policy to allow the unsigned request, use the policyFunc to obtain the relevant statement and call
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//           the handler again to verify its success.
  
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ExecObjectLayerAPIAnonTest ( t  * testing . T ,  testName ,  bucketName ,  objectName ,  instanceType  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq  * http . Request ,  policyFunc  func ( string ,  string )  policyStatement )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonTestStr  :=  "Anonymous HTTP request test" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unknownSignTestStr  :=  "Unknown HTTP signature test" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 15:41:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// simple function which returns a message which gives the context of the test
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// and then followed by the the actual error message.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 15:41:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									failTestStr  :=  func ( testType ,  failMsg  string )  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Sprintf ( "Minio %s: %s fail for \"%s\": \n<Error> %s" ,  instanceType ,  testType ,  testName ,  failMsg ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 04:51:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// httptest Recorder to capture all the response by the http handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// reading the body to preserve it so that it can be used again for second attempt of sending unsigned HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// If the body is read in the handler the same request cannot be made use of.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buf ,  err  :=  ioutil . ReadAll ( anonReq . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 15:41:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatal ( failTestStr ( anonTestStr ,  err . Error ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 00:21:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// creating 2 read closer (to set as request body) from the body content.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									readerOne  :=  ioutil . NopCloser ( bytes . NewBuffer ( buf ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									readerTwo  :=  ioutil . NopCloser ( bytes . NewBuffer ( buf ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									readerThree  :=  ioutil . NopCloser ( bytes . NewBuffer ( buf ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq . Body  =  readerOne 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// call the HTTP handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( rec ,  anonReq ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// expected error response when the unsigned HTTP request is not permitted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									accesDeniedHTTPStatus  :=  getAPIError ( ErrAccessDenied ) . HTTPStatusCode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rec . Code  !=  accesDeniedHTTPStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 15:41:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatal ( failTestStr ( anonTestStr ,  fmt . Sprintf ( "Object API Nil Test expected to fail with %d, but failed with %d" ,  accesDeniedHTTPStatus ,  rec . Code ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// expected error response in bytes when objectLayer is not initialized, or set to `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									expectedErrResponse  :=  encodeResponse ( getAPIErrorResponse ( getAPIError ( ErrAccessDenied ) ,  getGetObjectURL ( "" ,  bucketName ,  objectName ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 00:21:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HEAD HTTTP request doesn't contain response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  anonReq . Method  !=  "HEAD"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// read the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										actualContent ,  err  :=  ioutil . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 15:41:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatal ( failTestStr ( anonTestStr ,  fmt . Sprintf ( "Failed parsing response body: <ERROR> %v" ,  err ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 00:21:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// verify whether actual error response (from the response body), matches the expected error response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! bytes . Equal ( expectedErrResponse ,  actualContent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 15:41:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatal ( failTestStr ( anonTestStr ,  "error response content differs from expected value" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 00:21:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set write only policy on bucket to allow anonymous HTTP request for the operation under test.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// request to go through.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									policy  :=  bucketPolicy { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Version :     "1.0" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Statements :  [ ] policyStatement { policyFunc ( bucketName ,  "" ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalBucketPolicies . SetBucketPolicy ( bucketName ,  policyChange { false ,  & policy } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// now call the handler again with the unsigned/anonymous request, it should be accepted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq . Body  =  readerTwo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( rec ,  anonReq ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  expectedHTTPStatus  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// expectedHTTPStatus returns 204 (http.StatusNoContent) on success.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  testName  ==  "TestAPIDeleteObjectHandler"  ||  testName  ==  "TestAPIAbortMultipartHandler"  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										expectedHTTPStatus  =  http . StatusNoContent 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 00:21:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  strings . Contains ( testName ,  "BucketPolicyHandler" )  ||  testName  ==  "ListBucketsHandler"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// BucketPolicyHandlers and `ListBucketsHandler` doesn't support anonymous request, policy changes should allow unsigned requests.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										expectedHTTPStatus  =  http . StatusForbidden 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// other API handlers return 200OK on success.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expectedHTTPStatus  =  http . StatusOK 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 16:04:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 14:28:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// compare the HTTP response status code with the expected one.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rec . Code  !=  expectedHTTPStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 15:41:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatal ( failTestStr ( anonTestStr ,  fmt . Sprintf ( "Expected the anonymous HTTP request to be served after the policy changes\n,Expected response HTTP status code to be %d, got %d" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											expectedHTTPStatus ,  rec . Code ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// test for unknown auth case.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq . Body  =  readerThree 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Setting the `Authorization` header to a random value so that the signature falls into unknown auth case.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									anonReq . Header . Set ( "Authorization" ,  "nothingElse" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// initialize new response recorder.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// call the handler using the HTTP Request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( rec ,  anonReq ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// verify the response body for `ErrAccessDenied` message =.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  anonReq . Method  !=  "HEAD"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// read the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										actualContent ,  err  :=  ioutil . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 15:41:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatal ( failTestStr ( unknownSignTestStr ,  fmt . Sprintf ( "Failed parsing response body: <ERROR> %v" ,  err ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// verify whether actual error response (from the response body), matches the expected error response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! bytes . Equal ( expectedErrResponse ,  actualContent )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fmt . Println ( string ( expectedErrResponse ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fmt . Println ( string ( actualContent ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 15:41:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatal ( failTestStr ( unknownSignTestStr ,  "error response content differs from expected value" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rec . Code  !=  accesDeniedHTTPStatus  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 15:41:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatal ( failTestStr ( unknownSignTestStr ,  fmt . Sprintf ( "Object API Unknow auth test for \"%s\", expected to fail with %d, but failed with %d" ,  testName ,  accesDeniedHTTPStatus ,  rec . Code ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ExecObjectLayerAPINilTest - Sets the object layer to `nil`, and calls rhe registered object layer API endpoint,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// and assert the error response. The purpose is to validate the API handlers response when the object layer is uninitialized.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Usage hint: Should be used at the end of the API end points tests (ex: check the last few lines of `testAPIListObjectPartsHandler`),
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// need a sample HTTP request to be sent as argument so that the relevant handler is called, the handler registration is expected
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// to be done since its called from within the API handler tests, the reference to the registered HTTP handler has to be sent
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// as an argument.
  
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ExecObjectLayerAPINilTest ( t  TestErrHandler ,  bucketName ,  objectName ,  instanceType  string ,  apiRouter  http . Handler ,  req  * http . Request )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// httptest Recorder to capture all the response by the http handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// The  API handler gets the referece to the object layer via the global object Layer,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// setting it to `nil` in order test for handlers response for uninitialized object layer.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 14:03:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjLayerMutex . Lock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjectAPI  =  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 14:03:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjLayerMutex . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// call the HTTP handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// expected error response when the API handler is called before the object layer is initialized,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// or when objectLayer is `nil`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									serverNotInitializedErr  :=  getAPIError ( ErrServerNotInitialized ) . HTTPStatusCode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rec . Code  !=  serverNotInitializedErr  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-16 10:14:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Errorf ( "Object API Nil Test expected to fail with %d, but failed with %d" ,  serverNotInitializedErr ,  rec . Code ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// expected error response in bytes when objectLayer is not initialized, or set to `nil`.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									expectedErrResponse  :=  encodeResponse ( getAPIErrorResponse ( getAPIError ( ErrServerNotInitialized ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										getGetObjectURL ( "" ,  bucketName ,  objectName ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-11 15:00:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HEAD HTTP Request doesn't contain body in its response,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// for other type of HTTP requests compare the response body content with the expected one.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  req . Method  !=  "HEAD"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// read the response body.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										actualContent ,  err  :=  ioutil . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-16 10:14:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "Minio %s: Failed parsing response body: <ERROR> %v" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-11 15:00:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// verify whether actual error response (from the response body), matches the expected error response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! bytes . Equal ( expectedErrResponse ,  actualContent )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-16 10:14:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "Minio %s: Object content differs from expected value" ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-11 15:00:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ExecObjectLayerAPITest - executes object layer API tests.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Creates single node and XL ObjectLayer instance, registers the specified API end points and runs test for both the layers.
  
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ExecObjectLayerAPITest ( t  * testing . T ,  objAPITest  objAPITestType ,  endpoints  [ ] string )  {  
						 
					
						
							
								
									
										
										
										
											2017-01-08 03:27:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// reset globals.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// this is to make sure that the tests are not affected by modified value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetTestGlobals ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 04:51:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-08 03:27:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// initialize NSLock.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									initNSLock ( false ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 04:51:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-21 16:25:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// initialize the server and obtain the credentials and root.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// credentials are necessary to sign the HTTP request.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rootPath ,  err  :=  newTestConfig ( globalMinioDefaultRegion ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-21 16:25:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Unable to initialize server config. %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  fsDir ,  err  :=  prepareFS ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of object layer failed for single node setup: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bucketFS ,  fsAPIRouter ,  err  :=  initAPIHandlerTest ( objLayer ,  endpoints ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialzation of API handler tests failed: <ERROR> %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									credentials  :=  serverConfig . GetCredential ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Executing the object layer tests for single node setup.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-02 01:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objAPITest ( objLayer ,  FSTestStr ,  bucketFS ,  fsAPIRouter ,  credentials ,  t ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objLayer ,  xlDisks ,  err  :=  prepareXL ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of object layer failed for XL setup: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bucketXL ,  xlAPIRouter ,  err  :=  initAPIHandlerTest ( objLayer ,  endpoints ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialzation of API handler tests failed: <ERROR> %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Executing the object layer tests for XL.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-02 01:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objAPITest ( objLayer ,  XLTestStr ,  bucketXL ,  xlAPIRouter ,  credentials ,  t ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// clean up the temporary test backend.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-21 16:25:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									removeRoots ( append ( xlDisks ,  fsDir ,  rootPath ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// function to be passed to ExecObjectLayerAPITest, for executing object layr API handler tests.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  objAPITestType  func ( obj  ObjectLayer ,  instanceType  string ,  bucketName  string ,  
						 
					
						
							
								
									
										
										
										
											2016-10-07 23:02:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									apiRouter  http . Handler ,  credentials  credential ,  t  * testing . T ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Regular object test type.
  
						 
					
						
							
								
									
										
										
										
											2016-07-08 06:05:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  objTestType  func ( obj  ObjectLayer ,  instanceType  string ,  t  TestErrHandler )  
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Special object test type for disk not found situations.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  objTestDiskNotFoundType  func ( obj  ObjectLayer ,  instanceType  string ,  dirs  [ ] string ,  t  * testing . T )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ExecObjectLayerTest - executes object layer tests.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Creates single node and XL ObjectLayer instance and runs test for both the layers.
  
						 
					
						
							
								
									
										
										
										
											2016-07-08 06:05:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ExecObjectLayerTest ( t  TestErrHandler ,  objTest  objTestType )  {  
						 
					
						
							
								
									
										
										
										
											2016-10-21 16:25:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// initialize the server and obtain the credentials and root.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// credentials are necessary to sign the HTTP request.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rootPath ,  err  :=  newTestConfig ( globalMinioDefaultRegion ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-21 16:25:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Unexpected error" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  removeAll ( rootPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  fsDir ,  err  :=  prepareFS ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of object layer failed for single node setup: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-27 05:43:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Executing the object layer tests for single node setup.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-02 01:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objTest ( objLayer ,  FSTestStr ,  t ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-21 11:48:47 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  fsDirs ,  err  :=  prepareXL ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of object layer failed for XL setup: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Executing the object layer tests for XL.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-02 01:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objTest ( objLayer ,  XLTestStr ,  t ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									defer  removeRoots ( append ( fsDirs ,  fsDir ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-21 07:09:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ExecObjectLayerDiskAlteredTest - executes object layer tests while altering
  
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// disks in between tests. Creates XL ObjectLayer instance and runs test for XL layer.
  
						 
					
						
							
								
									
										
										
										
											2016-10-21 07:09:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ExecObjectLayerDiskAlteredTest ( t  * testing . T ,  objTest  objTestDiskNotFoundType )  {  
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									configPath ,  err  :=  newTestConfig ( globalMinioDefaultRegion ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-29 19:13:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Failed to create config directory" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  removeAll ( configPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  fsDirs ,  err  :=  prepareXL ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of object layer failed for XL setup: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 04:51:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Executing the object layer tests for XL.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-02 01:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objTest ( objLayer ,  XLTestStr ,  fsDirs ,  t ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									defer  removeRoots ( fsDirs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-06-29 17:28:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Special object test type for stale files situations.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  objTestStaleFilesType  func ( obj  ObjectLayer ,  instanceType  string ,  dirs  [ ] string ,  t  * testing . T )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ExecObjectLayerStaleFilesTest - executes object layer tests those leaves stale
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// files/directories under .minio/tmp.  Creates XL ObjectLayer instance and runs test for XL layer.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ExecObjectLayerStaleFilesTest ( t  * testing . T ,  objTest  objTestStaleFilesType )  {  
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									configPath ,  err  :=  newTestConfig ( globalMinioDefaultRegion ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-01 12:56:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Failed to create config directory" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  removeAll ( configPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nDisks  :=  16 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									erasureDisks ,  err  :=  getRandomDisks ( nDisks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of disks for XL setup: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									endpoints ,  err  :=  parseStorageEndpoints ( erasureDisks ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-19 03:49:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of disks for XL setup: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-12 08:36:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  _ ,  err  :=  initObjectLayer ( endpoints ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-29 17:28:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of object layer failed for XL setup: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-29 17:28:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Executing the object layer tests for XL.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-02 01:21:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objTest ( objLayer ,  XLTestStr ,  erasureDisks ,  t ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  removeRoots ( erasureDisks ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-29 17:28:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  registerBucketLevelFunc ( bucket  * router . Router ,  api  objectAPIHandlers ,  apiFunctions  ... string )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  apiFunction  :=  range  apiFunctions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  apiFunction  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "PostPolicy" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Register PostPolicy handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket . Methods ( "POST" ) . HeadersRegexp ( "Content-Type" ,  "multipart/form-data*" ) . HandlerFunc ( api . PostPolicyBucketHandler ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "HeadObject" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Register HeadObject handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket . Methods ( "Head" ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . HeadObjectHandler ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "GetObject" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register GetObject handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "GET" ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . GetObjectHandler ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "PutObject" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register PutObject handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "PUT" ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . PutObjectHandler ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "DeleteObject" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register Delete Object handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "DELETE" ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . DeleteObjectHandler ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "CopyObject" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register Copy Object  handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "PUT" ) . Path ( "/{object:.+}" ) . HeadersRegexp ( "X-Amz-Copy-Source" ,  ".*?(\\/|%2F).*?" ) . HandlerFunc ( api . CopyObjectHandler ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "PutBucketPolicy" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register PutBucket Policy handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "PUT" ) . HandlerFunc ( api . PutBucketPolicyHandler ) . Queries ( "policy" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "DeleteBucketPolicy" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register Delete bucket HTTP policy handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "DELETE" ) . HandlerFunc ( api . DeleteBucketPolicyHandler ) . Queries ( "policy" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "GetBucketPolicy" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register Get Bucket policy HTTP Handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "GET" ) . HandlerFunc ( api . GetBucketPolicyHandler ) . Queries ( "policy" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "GetBucketLocation" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register GetBucketLocation handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "GET" ) . HandlerFunc ( api . GetBucketLocationHandler ) . Queries ( "location" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "HeadBucket" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register HeadBucket handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "HEAD" ) . HandlerFunc ( api . HeadBucketHandler ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-17 01:46:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "DeleteMultipleObjects" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Register DeleteMultipleObjects handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket . Methods ( "POST" ) . HandlerFunc ( api . DeleteMultipleObjectsHandler ) . Queries ( "delete" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "NewMultipart" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register New Multipart upload handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "POST" ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . NewMultipartUploadHandler ) . Queries ( "uploads" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "CopyObjectPart" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Register CopyObjectPart handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket . Methods ( "PUT" ) . Path ( "/{object:.+}" ) . HeadersRegexp ( "X-Amz-Copy-Source" ,  ".*?(\\/|%2F).*?" ) . HandlerFunc ( api . CopyObjectPartHandler ) . Queries ( "partNumber" ,  "{partNumber:[0-9]+}" ,  "uploadId" ,  "{uploadId:.*}" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "PutObjectPart" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register PutObjectPart handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "PUT" ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . PutObjectPartHandler ) . Queries ( "partNumber" ,  "{partNumber:[0-9]+}" ,  "uploadId" ,  "{uploadId:.*}" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "ListObjectParts" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register ListObjectParts handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "GET" ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . ListObjectPartsHandler ) . Queries ( "uploadId" ,  "{uploadId:.*}" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "ListMultipartUploads" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register ListMultipartUploads handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "GET" ) . HandlerFunc ( api . ListMultipartUploadsHandler ) . Queries ( "uploads" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "CompleteMultipart" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register Complete Multipart Upload handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "POST" ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . CompleteMultipartUploadHandler ) . Queries ( "uploadId" ,  "{uploadId:.*}" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "AbortMultipart" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Register AbortMultipart Handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket . Methods ( "DELETE" ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . AbortMultipartUploadHandler ) . Queries ( "uploadId" ,  "{uploadId:.*}" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "GetBucketNotification" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register GetBucketNotification Handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "GET" ) . HandlerFunc ( api . GetBucketNotificationHandler ) . Queries ( "notification" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "PutBucketNotification" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register PutBucketNotification Handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "PUT" ) . HandlerFunc ( api . PutBucketNotificationHandler ) . Queries ( "notification" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "ListenBucketNotification" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register ListenBucketNotification Handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( "GET" ) . HandlerFunc ( api . ListenBucketNotificationHandler ) . Queries ( "events" ,  "{events:.*}" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// registerAPIFunctions helper function to add API functions identified by name to the routers.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  registerAPIFunctions ( muxRouter  * router . Router ,  objLayer  ObjectLayer ,  apiFunctions  ... string )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( apiFunctions )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Register all api endpoints by default.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										registerAPIRouter ( muxRouter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// API Router.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter  :=  muxRouter . NewRoute ( ) . PathPrefix ( "/" ) . Subrouter ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Bucket router.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bucketRouter  :=  apiRouter . PathPrefix ( "/{bucket}" ) . Subrouter ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// All object storage operations are registered as HTTP handlers on `objectAPIHandlers`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// When the handlers get a HTTP request they use the underlyting ObjectLayer to perform operations.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 14:03:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjLayerMutex . Lock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:47:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjectAPI  =  objLayer 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 14:03:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjLayerMutex . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:47:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									api  :=  objectAPIHandlers { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:47:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ObjectAPI :  newObjectLayerFn , 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:47:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Register ListBuckets	handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiRouter . Methods ( "GET" ) . HandlerFunc ( api . ListBucketsHandler ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Register all bucket level handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									registerBucketLevelFunc ( bucketRouter ,  api ,  apiFunctions ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Takes in XL object layer, and the list of API end points to be tested/required, registers the API end points and returns the HTTP handler.
  
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Need isolated registration of API end points while writing unit tests for end points.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// All the API end points are registered only for the default case.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  initTestAPIEndPoints ( objLayer  ObjectLayer ,  apiFunctions  [ ] string )  http . Handler  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// initialize a new mux router.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// goriilla/mux is the library used to register all the routes and handle them.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									muxRouter  :=  router . NewRouter ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( apiFunctions )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Iterate the list of API functions requested for and register them in mux HTTP handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										registerAPIFunctions ( muxRouter ,  objLayer ,  apiFunctions ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  muxRouter 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									registerAPIRouter ( muxRouter ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  muxRouter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-08-16 07:13:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-29 10:31:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Initialize Web RPC Handlers for testing
  
						 
					
						
							
								
									
										
										
										
											2016-08-16 07:13:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  initTestWebRPCEndPoint ( objLayer  ObjectLayer )  http . Handler  {  
						 
					
						
							
								
									
										
										
										
											2016-10-10 14:03:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjLayerMutex . Lock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjectAPI  =  objLayer 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 14:03:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalObjLayerMutex . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-16 07:13:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Initialize router.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									muxRouter  :=  router . NewRouter ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									registerWebRouter ( muxRouter ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-16 07:13:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  muxRouter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-11-08 03:43:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Initialize browser RPC endpoint.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  initTestBrowserPeerRPCEndPoint ( )  http . Handler  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Initialize router.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									muxRouter  :=  router . NewRouter ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									registerBrowserPeerRPCRouter ( muxRouter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  muxRouter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  StartTestBrowserPeerRPCServer ( t  TestErrHandler ,  instanceType  string )  TestServer  {  
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									root ,  err  :=  newTestConfig ( globalMinioDefaultRegion ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 03:43:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Create an instance of TestServer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer  :=  TestServer { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Fetch credentials for the test server.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									credentials  :=  serverConfig . GetCredential ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . Root  =  root 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testRPCServer . AccessKey  =  credentials . AccessKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . SecretKey  =  credentials . SecretKey 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 03:43:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Initialize and run the TestServer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . Server  =  httptest . NewServer ( initTestBrowserPeerRPCEndPoint ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  testRPCServer 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 08:43:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  StartTestS3PeerRPCServer ( t  TestErrHandler )  ( TestServer ,  [ ] string )  {  
						 
					
						
							
								
									
										
										
										
											2017-01-19 04:24:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									root ,  err  :=  newTestConfig ( globalMinioDefaultRegion ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 08:43:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Create an instance of TestServer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer  :=  TestServer { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Fetch credentials for the test server.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									credentials  :=  serverConfig . GetCredential ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . Root  =  root 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testRPCServer . AccessKey  =  credentials . AccessKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . SecretKey  =  credentials . SecretKey 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 03:43:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 08:43:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// init disks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objLayer ,  fsDirs ,  err  :=  prepareXL ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// set object layer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . Obj  =  objLayer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalObjLayerMutex . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalObjectAPI  =  objLayer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalObjLayerMutex . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Register router on a new mux
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									muxRouter  :=  router . NewRouter ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  registerS3PeerRPCRouter ( muxRouter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "%s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Initialize and run the TestServer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testRPCServer . Server  =  httptest . NewServer ( muxRouter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  testRPCServer ,  fsDirs 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 03:43:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// generateTLSCertKey creates valid key/cert with registered DNS or IP address
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// depending on the passed parameter. That way, we can use tls config without
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// passing InsecureSkipVerify flag.  This code is a simplified version of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// https://golang.org/src/crypto/tls/generate_cert.go
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  generateTLSCertKey ( host  string )  ( [ ] byte ,  [ ] byte ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									validFor  :=  365  *  24  *  time . Hour 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rsaBits  :=  2048 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( host )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  fmt . Errorf ( "Missing host parameter" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									publicKey  :=  func ( priv  interface { } )  interface { }  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  k  :=  priv . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  * rsa . PrivateKey : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  & k . PublicKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  * ecdsa . PrivateKey : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  & k . PublicKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pemBlockForKey  :=  func ( priv  interface { } )  * pem . Block  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  k  :=  priv . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  * rsa . PrivateKey : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  & pem . Block { Type :  "RSA PRIVATE KEY" ,  Bytes :  x509 . MarshalPKCS1PrivateKey ( k ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  * ecdsa . PrivateKey : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											b ,  err  :=  x509 . MarshalECPrivateKey ( k ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fmt . Fprintf ( os . Stderr ,  "Unable to marshal ECDSA private key: %v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												os . Exit ( 2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  & pem . Block { Type :  "EC PRIVATE KEY" ,  Bytes :  b } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  priv  interface { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									priv ,  err  =  rsa . GenerateKey ( crand . Reader ,  rsaBits ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  fmt . Errorf ( "failed to generate private key: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									notBefore  :=  time . Now ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									notAfter  :=  notBefore . Add ( validFor ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									serialNumberLimit  :=  new ( big . Int ) . Lsh ( big . NewInt ( 1 ) ,  128 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									serialNumber ,  err  :=  crand . Int ( crand . Reader ,  serialNumberLimit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  fmt . Errorf ( "failed to generate serial number: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									template  :=  x509 . Certificate { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SerialNumber :  serialNumber , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Subject :  pkix . Name { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Organization :  [ ] string { "Acme Co" } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										NotBefore :  notBefore , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										NotAfter :   notAfter , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										KeyUsage :               x509 . KeyUsageKeyEncipherment  |  x509 . KeyUsageDigitalSignature , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ExtKeyUsage :            [ ] x509 . ExtKeyUsage { x509 . ExtKeyUsageServerAuth } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BasicConstraintsValid :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hosts  :=  strings . Split ( host ,  "," ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  h  :=  range  hosts  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ip  :=  net . ParseIP ( h ) ;  ip  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											template . IPAddresses  =  append ( template . IPAddresses ,  ip ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											template . DNSNames  =  append ( template . DNSNames ,  h ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									template . IsCA  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									template . KeyUsage  |=  x509 . KeyUsageCertSign 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									derBytes ,  err  :=  x509 . CreateCertificate ( crand . Reader ,  & template ,  & template ,  publicKey ( priv ) ,  priv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  fmt . Errorf ( "Failed to create certificate: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									certOut  :=  bytes . NewBuffer ( [ ] byte { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pem . Encode ( certOut ,  & pem . Block { Type :  "CERTIFICATE" ,  Bytes :  derBytes } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									keyOut  :=  bytes . NewBuffer ( [ ] byte { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pem . Encode ( keyOut ,  pemBlockForKey ( priv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  certOut . Bytes ( ) ,  keyOut . Bytes ( ) ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}