2021-04-19 03:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Copyright (c) 2015-2021 MinIO, Inc.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This file is part of MinIO Object Storage stack
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is free software: you can redistribute it and/or modify
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// it under the terms of the GNU Affero General Public License as published by
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the Free Software Foundation, either version 3 of the License, or
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// (at your option) any later version.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This program is distributed in the hope that it will be useful
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// but WITHOUT ANY WARRANTY; without even the implied warranty of
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GNU Affero General Public License for more details.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// You should have received a copy of the GNU Affero General Public License
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// along with this program.  If not, see <http://www.gnu.org/licenses/>.
  
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-19 07:23:42 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  cmd  
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2022-05-24 21:26:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"archive/zip" 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"bufio" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"bytes" 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/ecdsa" 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-27 02:00:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"crypto/hmac" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									crand  "crypto/rand" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"crypto/rsa" 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-27 02:00:07 +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" 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-27 02:00:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/base64" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"encoding/hex" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/pem" 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/xml" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-16 07:13:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-29 00:18:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"flag" 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
									
										
										
										
											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" 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-08 13:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"path" 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-24 21:26:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"path/filepath" 
							 
						 
					
						
							
								
									
										
										
										
											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" 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-12 22:20:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"unsafe" 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/fatih/color" 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-30 08:00:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-15 00:38:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v7/pkg/s3utils" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v7/pkg/signer" 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-02 05:59:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/auth" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/config" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/crypto" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/hash" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/internal/logger" 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-23 19:12:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/mux" 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-05 03:57:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/pkg/v2/policy" 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-29 00:18:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TestMain to set up global env.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestMain ( m  * testing . M )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									flag . Parse ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 23:43:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-16 20:36:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// set to 'true' when testing is invoked
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalIsTesting  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-31 01:58:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalIsCICD  =  globalIsTesting 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-12 13:19:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalActiveCred  =  auth . Credentials { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AccessKey :  auth . DefaultAccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SecretKey :  auth . DefaultSecretKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-15 14:59:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// disable ENVs which interfere with tests.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  env  :=  range  [ ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										crypto . EnvKMSAutoEncryption , 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-30 01:55:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										config . EnvAccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										config . EnvSecretKey , 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-28 13:41:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										config . EnvRootUser , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										config . EnvRootPassword , 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-15 14:59:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										os . Unsetenv ( env ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-23 23:12:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set as non-distributed.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalIsDistErasure  =  false 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-23 23:12:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-30 23:23:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Disable printing console messages during tests.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									color . Output  =  io . Discard 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-30 23:23:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Minimum is error logs for testing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									logger . MinimumLogLevel  =  logger . ErrorLvl 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-29 00:18:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Uncomment the following line to see trace logs during unit tests.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// logger.AddTarget(console.New())
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-09 12:35:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-03 02:34:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set system resources to maximum.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									setMaxResources ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 09:45:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-17 12:30:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Initialize globalConsoleSys system
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalConsoleSys  =  NewConsoleLogger ( context . Background ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-17 05:49:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-13 12:31:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalInternodeTransport  =  NewInternodeHTTPTransport ( ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-02 23:43:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-05 07:32:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									initHelp ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetTestGlobals ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-29 00:18:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-14 07:42:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalIsCICD  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-13 08:10:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-29 00:18:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									os . Exit ( m . Run ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-08 10:50:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-29 00:18:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// concurrency level for certain parallel tests.
  
						 
					
						
							
								
									
										
										
										
											2017-10-10 17:14:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  testConcurrencyLevel  =  10  
						 
					
						
							
								
									
										
										
										
											2017-10-10 07:41:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-13 02:28:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  iso8601TimeFormat  =  "2006-01-02T15:04:05.000Z"  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Excerpts from @lsegal - https://github.com/aws/aws-sdk-js/issues/659#issuecomment-120477258
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
									
										
										
										
											2022-08-27 03:52:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	User-Agent:
  
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
									
										
										
										
											2022-08-27 03:52:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	    This is ignored from signing because signing this causes problems with generating pre-signed URLs
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    (that are executed by other agents) or when customers pass requests through proxies, which may
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	    modify the user-agent.
  
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
									
										
										
										
											2022-08-27 03:52:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	Authorization:
  
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
									
										
										
										
											2022-08-27 03:52:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//	    Is skipped for obvious reasons
  
						 
					
						
							
								
									
										
										
										
											2017-10-10 07:41:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  ignoredHeaders  =  map [ string ] bool {  
						 
					
						
							
								
									
										
										
										
											2020-04-14 14:21:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"Authorization" :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"User-Agent" :     true , 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-10 07:41:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Headers to ignore in streaming v4
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  ignoredStreamingHeaders  =  map [ string ] bool {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"Authorization" :  true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"Content-Type" :   true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"Content-Md5" :    true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"User-Agent" :     true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// calculateSignedChunkLength - calculates the length of chunk metadata
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  calculateSignedChunkLength ( chunkDataSize  int64 )  int64  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  int64 ( len ( fmt . Sprintf ( "%x" ,  chunkDataSize ) ) )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										17  +  // ";chunk-signature="
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										64  +  // e.g. "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										2  +  // CRLF
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										chunkDataSize  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										2  // CRLF
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-11-15 09:36:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  mustGetPutObjReader ( t  TestErrHandler ,  data  io . Reader ,  size  int64 ,  md5hex ,  sha256hex  string )  * PutObjReader  {  
						 
					
						
							
								
									
										
										
										
											2023-09-19 01:00:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hr ,  err  :=  hash . NewReader ( context . Background ( ) ,  data ,  size ,  md5hex ,  sha256hex ,  size ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-11 00:52:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  NewPutObjReader ( hr ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-10 07:41:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// calculateSignedChunkLength - calculates the length of the overall stream (data + metadata)
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  calculateStreamContentLength ( dataLen ,  chunkSize  int64 )  int64  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  dataLen  <=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-08-25 03:11:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									chunksCount  :=  dataLen  /  chunkSize 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									remainingBytes  :=  dataLen  %  chunkSize 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-10 07:41:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  streamLen  int64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									streamLen  +=  chunksCount  *  calculateSignedChunkLength ( chunkSize ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  remainingBytes  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										streamLen  +=  calculateSignedChunkLength ( remainingBytes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									streamLen  +=  calculateSignedChunkLength ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  streamLen 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  prepareFS ( ctx  context . Context )  ( 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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-04 00:47:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									obj ,  _ ,  err  :=  initObjectLayer ( context . Background ( ) ,  mustGetPoolEndpoints ( 0 ,  fsDirs ... ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-31 01:58:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									initAllSubsystems ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-31 01:58:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalIAMSys . Init ( ctx ,  obj ,  globalEtcdClient ,  2 * time . Second ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  obj ,  fsDirs [ 0 ] ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  prepareErasureSets32 ( ctx  context . Context )  ( ObjectLayer ,  [ ] string ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  prepareErasure ( ctx ,  32 ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 09:45:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  prepareErasure ( ctx  context . Context ,  nDisks  int )  ( ObjectLayer ,  [ ] string ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									fsDirs ,  err  :=  getRandomDisks ( nDisks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-04 00:47:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									obj ,  _ ,  err  :=  initObjectLayer ( ctx ,  mustGetPoolEndpoints ( 0 ,  fsDirs ... ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										removeRoots ( fsDirs ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-27 00:04:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  obj ,  fsDirs ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  prepareErasure16 ( ctx  context . Context )  ( ObjectLayer ,  [ ] string ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  prepareErasure ( ctx ,  16 ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 01:32:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TestErrHandler - Go testing.T satisfy this interface.
  
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// This makes it easy to run the TestServer from any of the tests.
  
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +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  {  
						 
					
						
							
								
									
										
										
										
											2021-03-30 08:00:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testing . TB 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
									
										
										
										
											2022-05-31 01:58:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// ErasureSDStr is the string which is used as notation for Single node ObjectLayer in the unit tests.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ErasureSDStr  string  =  "ErasureSD" 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-17 09:05:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// ErasureTestStr is the string which is used as notation for Erasure ObjectLayer in the unit tests.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ErasureTestStr  string  =  "Erasure" 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 09:45:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// ErasureSetsTestStr is the string which is used as notation for Erasure sets object layer in the unit tests.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ErasureSetsTestStr  string  =  "ErasureSet" 
							 
						 
					
						
							
								
									
										
										
										
											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.
  
						 
					
						
							
								
									
										
										
										
											2022-01-07 05:08:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									randN   uint32 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									randmu  sync . Mutex 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
									
										
										
										
											2016-06-29 18:13:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// TestServer encapsulates an instantiation of a MinIO instance with a temporary backend.
  
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Example usage:
  
						 
					
						
							
								
									
										
										
										
											2022-08-27 03:52:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	s := StartTestServer(t,"Erasure")
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	defer s.Stop()
  
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  TestServer  struct  {  
						 
					
						
							
								
									
										
										
										
											2021-11-04 23:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Root          string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Disks         EndpointServerPools 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AccessKey     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SecretKey     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Server        * httptest . Server 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Obj           ObjectLayer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cancel        context . CancelFunc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rawDiskPaths  [ ] string 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// UnstartedTestServer - Configures a temp FS/Erasure backend,
  
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// 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  {  
						 
					
						
							
								
									
										
										
										
											2020-04-15 08:52:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx ,  cancel  :=  context . WithCancel ( context . Background ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// create an instance of TestServer.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 08:52:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer  :=  TestServer { cancel :  cancel } 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// return FS/Erasure object layer and temp backend.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-15 08:52:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  disks ,  err  :=  prepareTestBackend ( ctx ,  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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-15 12:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 23:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// set new server configuration.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-15 12:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  newTestConfig ( globalMinioDefaultRegion ,  objLayer ) ;  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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 23:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  initTestServerWithBackend ( ctx ,  t ,  testServer ,  objLayer ,  disks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// initializes a test server with the given object layer and disks.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  initTestServerWithBackend ( ctx  context . Context ,  t  TestErrHandler ,  testServer  TestServer ,  objLayer  ObjectLayer ,  disks  [ ] string )  TestServer  {  
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  :=  globalActiveCred 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . Obj  =  objLayer 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 23:16:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . rawDiskPaths  =  disks 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-04 00:47:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . Disks  =  mustGetPoolEndpoints ( 0 ,  disks ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . AccessKey  =  credentials . AccessKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testServer . SecretKey  =  credentials . SecretKey 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-25 15:17:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									httpHandler ,  err  :=  configureServerHandler ( testServer . Disks ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-01 23:04:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . Server  =  httptest . NewUnstartedServer ( setCriticalErrorHandler ( corsHandler ( httpHandler ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 00:19:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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
 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 06:44:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									host ,  port  :=  mustSplitHostPort ( testServer . Server . Listener . Addr ( ) . String ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-27 18:30:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalMinioHost  =  host 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalMinioPort  =  port 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 06:44:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalMinioAddr  =  getEndpointsLocalAddr ( testServer . Disks ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-10 09:50:31 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									initAllSubsystems ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-10 01:25:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalEtcdClient  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-18 05:42:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									initConfigSubsystem ( ctx ,  objLayer ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-05 17:42:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 02:39:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalIAMSys . Init ( ctx ,  objLayer ,  globalEtcdClient ,  2 * time . Second ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 23:14:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-28 08:23:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalEventNotifier . InitBucketTargets ( ctx ,  objLayer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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-12-14 03:51:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Sets the global config path to empty string.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  resetGlobalConfigPath ( )  {  
						 
					
						
							
								
									
										
										
										
											2019-01-03 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalConfigDir  =  & ConfigDir { path :  "" } 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-30 05:12:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalServerConfigMu . Lock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 03:51:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Save the loaded config globally.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-30 05:12:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalServerConfig  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalServerConfigMu . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 03:51:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-23 16:32:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  resetGlobalEndpoints ( )  {  
						 
					
						
							
								
									
										
										
										
											2020-12-02 05:50:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalEndpoints  =  EndpointServerPools { } 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-23 16:32:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  resetGlobalIsErasure ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalIsErasure  =  false 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-23 16:32:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-23 06:54:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// reset global heal state
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  resetGlobalHealState ( )  {  
						 
					
						
							
								
									
										
										
										
											2020-01-16 10:30:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Init global heal state
 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-09 13:14:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalAllHealState  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalAllHealState  =  newHealState ( GlobalContext ,  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-16 10:30:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalAllHealState . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  v  :=  range  globalAllHealState . healSeqMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! v . hasEnded ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												v . stop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalAllHealState . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-09 13:14:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-16 10:30:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Init background heal state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  globalBackgroundHealState  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalBackgroundHealState  =  newHealState ( GlobalContext ,  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-16 10:30:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										globalBackgroundHealState . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  v  :=  range  globalBackgroundHealState . healSeqMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! v . hasEnded ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												v . stop ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-23 06:54:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-16 10:30:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalBackgroundHealState . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-23 06:54:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 08:25:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// sets globalIAMSys to `nil`.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  resetGlobalIAMSys ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalIAMSys  =  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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-23 16:32:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Reset global endpoints.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalEndpoints ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Reset global isErasure flag.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalIsErasure ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-23 06:54:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Reset global heal state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalHealState ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 08:25:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Reset globalIAMSys to `nil`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetGlobalIAMSys ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-14 03:51:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Configure the server for the test run.
  
						 
					
						
							
								
									
										
										
										
											2018-08-15 12:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newTestConfig ( bucketLocation  string ,  obj  ObjectLayer )  ( err  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Initialize server config.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  newSrvConfig ( obj ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-15 12:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set a default region.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									config . SetRegion ( globalServerConfig ,  bucketLocation ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-27 00:04:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									applyDynamicConfigForSubSys ( context . Background ( ) ,  obj ,  globalServerConfig ,  config . StorageClassSubSys ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-26 15:01:35 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Save config.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 20:24:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  saveServerConfig ( context . Background ( ) ,  obj ,  globalServerConfig ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Deleting the temporary backend and stopping the server.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( testServer  TestServer )  Stop ( )  {  
						 
					
						
							
								
									
										
										
										
											2020-04-15 08:52:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . cancel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									testServer . Server . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 00:18:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									testServer . Obj . Shutdown ( context . Background ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-13 10:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									os . RemoveAll ( testServer . Root ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-20 09:42:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  ep  :=  range  testServer . Disks  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  disk  :=  range  ep . Endpoints  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											os . RemoveAll ( disk . Path ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newChunk ,  err  :=  io . ReadAll ( bufReader ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newReq  :=  req 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newReq . Body  =  io . NopCloser ( 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newChunk ,  err  :=  io . ReadAll ( bufReader ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newChunk [ 0 ]  =  newByte 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newReq  :=  req 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newReq . Body  =  io . NopCloser ( 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newChunk ,  err  :=  io . ReadAll ( bufReader ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newReq  :=  req 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newReq . Body  =  io . NopCloser ( 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 16:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req . URL . RawQuery  =  strings . ReplaceAll ( req . URL . Query ( ) . Encode ( ) ,  "+" ,  "%20" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get canonical URI.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-06 01:48:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									canonicalURI  :=  s3utils . EncodePath ( req . URL . Path ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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 , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-28 09:46:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										string ( serviceS3 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"aws4_request" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ,  SlashSeparator ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									stringToSign  :=  "AWS4-HMAC-SHA256"  +  "\n"  +  currTime . Format ( iso8601Format )  +  "\n" 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stringToSign  +=  scope  +  "\n" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-28 09:46:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									service  :=  sumHMAC ( region ,  [ ] byte ( string ( serviceS3 ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									signingKey  :=  sumHMAC ( service ,  [ ] byte ( "aws4_request" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signature  :=  hex . EncodeToString ( sumHMAC ( signingKey ,  [ ] byte ( stringToSign ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// final Authorization header
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parts  :=  [ ] string { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"AWS4-HMAC-SHA256"  +  " Credential="  +  accessKey  +  SlashSeparator  +  scope , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"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  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										method  =  http . MethodPost 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  http . NewRequest ( method ,  urlStr ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  body  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// this is added to avoid panic during io.ReadAll(req.Body).
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// 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.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req . Body  =  io . NopCloser ( bytes . NewReader ( [ ] byte ( "" ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req . Body  =  io . NopCloser ( body ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req . ContentLength  =  contentLength 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  req ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 14:46:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  assembleStreamingChunks ( req  * http . Request ,  body  io . ReadSeeker ,  chunkSize  int64 ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									secretKey ,  signature  string ,  currTime  time . Time )  ( * http . Request ,  error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2021-11-26 05:06:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									regionStr  :=  globalSite . Region 
							 
						 
					
						
							
								
									
										
										
										
											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 , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-28 09:46:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											string ( serviceS3 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											"aws4_request" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ,  SlashSeparator ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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(""))
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-28 09:46:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										service  :=  sumHMAC ( region ,  [ ] byte ( serviceS3 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req . Body  =  io . NopCloser ( bytes . NewReader ( stream ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-05 04:37:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									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" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 05:06:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									region  :=  globalSite . Region 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-06 08:00:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// "host" is the only header required to be signed for Presigned URLs.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									extractedSignedHeaders  :=  make ( http . Header ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									extractedSignedHeaders . Set ( "host" ,  req . Host ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 13:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									queryStr  :=  strings . ReplaceAll ( query . Encode ( ) ,  "+" ,  "%20" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-06 08:00:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									canonicalRequest  :=  getCanonicalRequest ( extractedSignedHeaders ,  unsignedPayload ,  queryStr ,  req . URL . Path ,  req . Method ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 05:09:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stringToSign  :=  getStringToSign ( canonicalRequest ,  date ,  scope ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-28 09:46:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									signingKey  :=  getSigningKey ( secretAccessKey ,  date ,  region ,  serviceS3 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 13:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									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-09-27 02:00:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// FIXME: Remove following portion of code after fixing a bug in minio-go preSignV2.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									d  :=  UTCNow ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Find epoch expires when the request will expire.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									epochExpires  :=  d . Unix ( )  +  expires 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Add expires header if not present.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 . SplitN ( req . URL . Path ,  "?" ,  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										encodedResource  =  splits [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( splits )  ==  2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											encodedQuery  =  splits [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unescapedQueries ,  err  :=  unescapeQueries ( encodedQuery ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Get presigned string to sign.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									stringToSign  :=  getStringToSignV2 ( req . Method ,  encodedResource ,  strings . Join ( unescapedQueries ,  "&" ) ,  req . Header ,  expiresStr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . URL . RawQuery  =  query . Encode ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Save signature finally.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . URL . RawQuery  +=  "&Signature="  +  url . QueryEscape ( signature ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Sign given request using Signature V2.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  signRequestV2 ( req  * http . Request ,  accessKey ,  secretKey  string )  error  {  
						 
					
						
							
								
									
										
										
										
											2020-04-15 07:53:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									signer . SignV2 ( * req ,  accessKey ,  secretKey ,  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-26 05:06:25 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									region  :=  globalSite . Region 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-15 14:53:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req . URL . RawQuery  =  strings . ReplaceAll ( req . URL . Query ( ) . Encode ( ) ,  "+" ,  "%20" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Get canonical URI.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-06 01:48:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									canonicalURI  :=  s3utils . EncodePath ( req . URL . Path ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 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 , 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-28 09:46:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										string ( serviceS3 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										"aws4_request" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ,  SlashSeparator ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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" 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									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 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-28 09:46:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									service  :=  sumHMAC ( regionHMAC ,  [ ] byte ( serviceS3 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											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 { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"AWS4-HMAC-SHA256"  +  " Credential="  +  accessKey  +  SlashSeparator  +  scope , 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 03:10:18 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										"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  {  
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  accessKeyID  +  SlashSeparator  +  getScope ( t ,  location ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-14 10:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-15 21:56:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// getMD5HashBase64 returns MD5 hash in base64 encoding of given data.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getMD5HashBase64 ( data  [ ] byte )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  base64 . StdEncoding . EncodeToString ( getMD5Sum ( data ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										method  =  http . MethodPost 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Save for subsequent use
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  hashedPayload  string 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-07 02:27:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  md5Base64  string 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  body  ==  nil : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-22 05:51:05 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hashedPayload  =  getSHA256Hash ( [ ] byte { } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										payloadBytes ,  err  :=  io . ReadAll ( body ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-07 02:27:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										md5Base64  =  getMD5HashBase64 ( payloadBytes ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Seek back to beginning.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  body  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										body . Seek ( 0 ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-07 02:27:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										body  =  bytes . NewReader ( [ ] byte ( "" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-07 02:27:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									req ,  err  :=  http . NewRequest ( method ,  urlStr ,  body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  md5Base64  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Header . Set ( "Content-Md5" ,  md5Base64 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . Header . Set ( "x-amz-content-sha256" ,  hashedPayload ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Add Content-Length
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req . ContentLength  =  contentLength 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-11 02:10:59 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  newTestSignedRequestV2 ( method ,  urlStr ,  contentLength ,  body ,  accessKey ,  secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  newTestSignedRequestV4 ( method ,  urlStr ,  contentLength ,  body ,  accessKey ,  secretKey ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-11 00:58:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Returns request with correct signature but with incorrect SHA256.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  newTestSignedBadSHARequest ( method ,  urlStr  string ,  contentLength  int64 ,  body  io . ReadSeeker ,  accessKey ,  secretKey  string ,  signer  signerType )  ( * http . Request ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  newTestRequest ( method ,  urlStr ,  contentLength ,  body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Anonymous request return early.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  accessKey  ==  ""  ||  secretKey  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  req ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  signer  ==  signerV2  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  signRequestV2 ( req ,  accessKey ,  secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Header . Del ( "x-amz-content-sha256" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										req . Header . Set ( "x-amz-content-sha256" ,  "92b165232fbd011da355eca0b033db22b934ba9af0145a437a832d27310b89f9" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  signRequestV4 ( req ,  accessKey ,  secretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  req ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Returns new HTTP request object signed with signature v2.
  
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newTestSignedRequestV2 ( method ,  urlStr  string ,  contentLength  int64 ,  body  io . ReadSeeker ,  accessKey ,  secretKey  string ,  headers  map [ string ] string )  ( * http . Request ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  k ,  v  :=  range  headers  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-02 07:58:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req . Header . Set ( k ,  v ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 05:32:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									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.
  
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newTestSignedRequestV4 ( method ,  urlStr  string ,  contentLength  int64 ,  body  io . ReadSeeker ,  accessKey ,  secretKey  string ,  headers  map [ string ] 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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  k ,  v  :=  range  headers  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-02 07:58:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req . Header . Set ( k ,  v ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-12 22:20:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  src  =  rand . NewSource ( time . Now ( ) . UnixNano ( ) )  
						 
					
						
							
								
									
										
										
										
											2020-09-23 06:34:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-12 22:20:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  randString ( n  int )  string  {  
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									b  :=  make ( [ ] byte ,  n ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-12 22:20:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									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 -- 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-12 22:20:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  * ( * string ) ( unsafe . Pointer ( & b ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// construct URL for http requests for bucket operations.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  makeTestTargetURL ( endPoint ,  bucketName ,  objectName  string ,  queryValues  url . Values )  string  {  
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									urlStr  :=  endPoint  +  SlashSeparator 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  bucketName  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										urlStr  =  urlStr  +  bucketName  +  SlashSeparator 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectName  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										urlStr  +=  s3utils . EncodePath ( 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-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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-08 07:12:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return URL for creating the bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getBucketVersioningConfigURL ( endPoint ,  bucketName  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									vals  :=  make ( url . Values ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									vals . Set ( "versioning" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  vals ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-06-26 10:07:44 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// 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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:06:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return URL For set/get lifecycle of the bucket.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getBucketLifecycleURL ( endPoint ,  bucketName  string )  ( ret  string )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "lifecycle" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  "" ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 03:32:05 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// return URL for listing objects in the bucket with V1 legacy API.
  
						 
					
						
							
								
									
										
										
										
											2019-02-24 14:14:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getListObjectsV1URL ( endPoint ,  bucketName ,  prefix ,  maxKeys ,  encodingType  string )  string  {  
						 
					
						
							
								
									
										
										
										
											2016-06-28 14:54:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  maxKeys  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queryValue . Set ( "max-keys" ,  maxKeys ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-24 14:14:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  encodingType  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queryValue . Set ( "encoding-type" ,  encodingType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  prefix ,  queryValue ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-28 14:54:56 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-08 07:12:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return URL for listing objects in the bucket with V1 legacy API.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getListObjectVersionsURL ( endPoint ,  bucketName ,  prefix ,  maxKeys ,  encodingType  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  maxKeys  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queryValue . Set ( "max-keys" ,  maxKeys ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  encodingType  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queryValue . Set ( "encoding-type" ,  encodingType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									queryValue . Set ( "versions" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  prefix ,  queryValue ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 03:32:05 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// return URL for listing objects in the bucket with V2 API.
  
						 
					
						
							
								
									
										
										
										
											2019-02-24 14:14:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getListObjectsV2URL ( endPoint ,  bucketName ,  prefix ,  maxKeys ,  fetchOwner ,  encodingType  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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-24 14:14:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  encodingType  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										queryValue . Set ( "encoding-type" ,  encodingType ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  makeTestTargetURL ( endPoint ,  bucketName ,  prefix ,  queryValue ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-18 03:32:05 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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-28 16:08:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return URL for listen bucket notification.
  
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getListenNotificationURL ( 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-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// getRandomDisks - Creates a slice of N random disks, each of the form - minio-XXX
  
						 
					
						
							
								
									
										
										
										
											2023-03-07 00:56:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getRandomDisks ( n  int )  ( [ ] string ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									var  erasureDisks  [ ] string 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-07 00:56:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <  n ;  i ++  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										path ,  err  :=  os . MkdirTemp ( 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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 09:45:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Initialize object layer with the supplied disks, objectLayer is nil upon any error.
  
						 
					
						
							
								
									
										
										
										
											2020-12-02 05:50:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  newTestObjectLayer ( ctx  context . Context ,  endpointServerPools  EndpointServerPools )  ( newObject  ObjectLayer ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									initAllSubsystems ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-10 01:27:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-31 01:58:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  newErasureServerPools ( ctx ,  endpointServerPools ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 09:45:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// initObjectLayer - Instantiates object layer and returns it.
  
						 
					
						
							
								
									
										
										
										
											2020-12-02 05:50:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  initObjectLayer ( ctx  context . Context ,  endpointServerPools  EndpointServerPools )  ( ObjectLayer ,  [ ] StorageAPI ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objLayer ,  err  :=  newTestObjectLayer ( ctx ,  endpointServerPools ) 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 09:45:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  formattedDisks  [ ] StorageAPI 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Should use the object layer tests for validating cache.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-02 05:50:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  z ,  ok  :=  objLayer . ( * erasureServerPools ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										formattedDisks  =  z . serverPools [ 0 ] . GetDisks ( 0 ) ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-16 09:45:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-13 10:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										os . 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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-17 01:28:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// removeDiskN - removes N disks from supplied disk slice.
  
						 
					
						
							
								
									
										
										
										
											2016-06-29 13:32:00 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  removeDiskN ( disks  [ ] string ,  n  int )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  n  >  len ( disks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n  =  len ( disks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  disk  :=  range  disks [ : n ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-13 10:25:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										os . RemoveAll ( disk ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
  
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  initAPIHandlerTest ( ctx  context . Context ,  obj  ObjectLayer ,  endpoints  [ ] string )  ( string ,  http . Handler ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									initAllSubsystems ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-18 05:42:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									initConfigSubsystem ( ctx ,  obj ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 02:39:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalIAMSys . Init ( ctx ,  obj ,  globalEtcdClient ,  2 * time . Second ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 23:14:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-23 23:46:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  :=  obj . MakeBucket ( context . Background ( ) ,  bucketName ,  MakeBucketOptions { } ) 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Register the API end points with Erasure 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 ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 20:59:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									f  :=  http . HandlerFunc ( func ( w  http . ResponseWriter ,  r  * http . Request )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-24 09:01:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										r . RequestURI  =  r . URL . RequestURI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( w ,  r ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 20:59:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-24 09:01:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  bucketName ,  f ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// prepare test backend.
  
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// create FS/Erasure/ErasureSet backend.
  
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// return object layer, backend disks.
  
						 
					
						
							
								
									
										
										
										
											2020-04-15 08:52:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  prepareTestBackend ( ctx  context . Context ,  instanceType  string )  ( ObjectLayer ,  [ ] string ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  instanceType  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Total number of disks for Erasure sets backend is set to 32.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ErasureSetsTestStr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  prepareErasureSets32 ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Total number of disks for Erasure backend is set to 16.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ErasureTestStr : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  prepareErasure16 ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// return FS backend by default.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										obj ,  disk ,  err  :=  prepareFS ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 10:05:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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.
  
						 
					
						
							
								
									
										
										
										
											2022-08-27 03:52:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	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.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The test works in 2 steps, here is the description of the steps.
  
						 
					
						
							
								
									
										
										
										
											2022-08-27 03:52:29 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//	STEP 1: Call the handler with the unsigned HTTP request (anonReq), assert for the `ErrAccessDenied` error response.
  
						 
					
						
							
								
									
										
										
										
											2018-02-10 07:19:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ExecObjectLayerAPIAnonTest ( t  * testing . T ,  obj  ObjectLayer ,  testName ,  bucketName ,  objectName ,  instanceType  string ,  apiRouter  http . Handler ,  
						 
					
						
							
								
									
										
										
										
											2023-09-05 03:57:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									anonReq  * http . Request ,  bucketPolicy  * policy . BucketPolicy , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											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
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-30 23:26:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// and then followed by the actual error message.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-21 15:41:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									failTestStr  :=  func ( testType ,  failMsg  string )  string  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									buf ,  err  :=  io . ReadAll ( anonReq . Body ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									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.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									readerOne  :=  io . NopCloser ( bytes . NewBuffer ( buf ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									readerTwo  :=  io . 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.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 03:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									accessDenied  :=  getAPIError ( ErrAccessDenied ) . HTTPStatusCode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rec . Code  !=  accessDenied  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( failTestStr ( anonTestStr ,  fmt . Sprintf ( "Object API Nil Test expected to fail with %d, but failed with %d" ,  accessDenied ,  rec . Code ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 00:21:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// HEAD HTTTP request doesn't contain response body.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  anonReq . Method  !=  http . MethodHead  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 00:21:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// read the response body.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  actualContent  [ ] byte 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										actualContent ,  err  =  io . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 00:21:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										actualError  :=  & APIErrorResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  xml . Unmarshal ( actualContent ,  actualError ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatal ( failTestStr ( anonTestStr ,  "error response failed to parse error XML" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actualError . BucketName  !=  bucketName  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatal ( failTestStr ( anonTestStr ,  "error response bucket name differs from expected value" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actualError . Key  !=  objectName  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatal ( failTestStr ( anonTestStr ,  "error response object name differs from expected value" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-10 00:21:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-08 02:16:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// test for unknown auth case.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									anonReq . Body  =  readerTwo 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// 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 =.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  anonReq . Method  !=  http . MethodHead  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// read the response body.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										actualContent ,  err  :=  io . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										actualError  :=  & APIErrorResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  xml . Unmarshal ( actualContent ,  actualError ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatal ( failTestStr ( unknownSignTestStr ,  "error response failed to parse error XML" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-08 13:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  path . Clean ( actualError . Resource )  !=  pathJoin ( SlashSeparator ,  bucketName ,  SlashSeparator ,  objectName )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatal ( failTestStr ( unknownSignTestStr ,  "error response resource differs from expected value" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 11:38:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-03 03:35:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// expected error response when the unsigned HTTP request is not permitted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsupportedSignature  :=  getAPIError ( ErrSignatureVersionNotSupported ) . HTTPStatusCode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  rec . Code  !=  unsupportedSignature  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( failTestStr ( unknownSignTestStr ,  fmt . Sprintf ( "Object API Unknow auth test for \"%s\", expected to fail with %d, but failed with %d" ,  testName ,  unsupportedSignature ,  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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  req . Method  !=  http . MethodHead  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-11 15:00:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// read the response body.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										actualContent ,  err  :=  io . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-11 15:00:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "MinIO %s: Failed parsing response body: <ERROR> %v" ,  instanceType ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-11 15:00:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										actualError  :=  & APIErrorResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  xml . Unmarshal ( actualContent ,  actualError ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "MinIO %s: error response failed to parse error XML" ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actualError . BucketName  !=  bucketName  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "MinIO %s: error response bucket name differs from expected value" ,  instanceType ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  actualError . Key  !=  objectName  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Errorf ( "MinIO %s: error response object name 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.
  
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Creates single node and Erasure 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 )  {  
						 
					
						
							
								
									
										
										
										
											2020-04-15 08:52:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx ,  cancel  :=  context . WithCancel ( context . Background ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  cancel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  fsDir ,  err  :=  prepareFS ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of object layer failed for single node setup: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bucketFS ,  fsAPIRouter ,  err  :=  initAPIHandlerTest ( ctx ,  objLayer ,  endpoints ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 08:25:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of API handler tests failed: <ERROR> %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-15 12:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// initialize the server and obtain the credentials and root.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// credentials are necessary to sign the HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  newTestConfig ( globalMinioDefaultRegion ,  objLayer ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Unable to initialize server config. %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credentials  :=  globalActiveCred 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-15 12:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Executing the object layer tests for single node setup.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-31 01:58:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objAPITest ( objLayer ,  ErasureSDStr ,  bucketFS ,  fsAPIRouter ,  credentials ,  t ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-27 00:04:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// reset globals.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// this is to make sure that the tests are not affected by modified value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resetTestGlobals ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  erasureDisks ,  err  :=  prepareErasure16 ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of object layer failed for Erasure setup: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 00:18:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  objLayer . Shutdown ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bucketErasure ,  erAPIRouter ,  err  :=  initAPIHandlerTest ( ctx ,  objLayer ,  endpoints ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Initialzation of API handler tests failed: <ERROR> %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-27 00:04:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// initialize the server and obtain the credentials and root.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// credentials are necessary to sign the HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  newTestConfig ( globalMinioDefaultRegion ,  objLayer ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Unable to initialize server config. %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Executing the object layer tests for Erasure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objAPITest ( objLayer ,  ErasureTestStr ,  bucketErasure ,  erAPIRouter ,  credentials ,  t ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-07 04:34:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// clean up the temporary test backend.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									removeRoots ( append ( erasureDisks ,  fsDir ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-11 05:47:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-06 12:08:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ExecExtendedObjectLayerTest will execute the tests with combinations of encrypted & compressed.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This can be used to test functionality when reading and writing data.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ExecExtendedObjectLayerAPITest ( t  * testing . T ,  objAPITest  objAPITestType ,  endpoints  [ ] string )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									execExtended ( t ,  func ( t  * testing . T )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ExecObjectLayerAPITest ( t ,  objAPITest ,  endpoints ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ,  
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									apiRouter  http . Handler ,  credentials  auth . Credentials ,  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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Special test type for test with directories
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  objTestTypeWithDirs  func ( obj  ObjectLayer ,  instanceType  string ,  dirs  [ ] 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.
  
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Creates single node and Erasure ObjectLayer instance and runs test for both the layers.
  
						 
					
						
							
								
									
										
										
										
											2016-07-08 06:05:51 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ExecObjectLayerTest ( t  TestErrHandler ,  objTest  objTestType )  {  
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctx ,  cancel  :=  context . WithCancel ( context . Background ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  localMetacacheMgr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											localMetacacheMgr . deleteAll ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-15 12:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										objLayer ,  fsDir ,  err  :=  prepareFS ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Initialization of object layer failed for single node setup: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										setObjectLayer ( objLayer ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										initAllSubsystems ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 23:14:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// initialize the server and obtain the credentials and root.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// credentials are necessary to sign the HTTP request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  newTestConfig ( globalMinioDefaultRegion ,  objLayer ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatal ( "Unexpected error" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-18 05:42:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										initConfigSubsystem ( ctx ,  objLayer ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 02:39:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalIAMSys . Init ( ctx ,  objLayer ,  globalEtcdClient ,  2 * time . Second ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-21 11:48:47 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Executing the object layer tests for single node setup.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-31 01:58:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										objTest ( objLayer ,  ErasureSDStr ,  t ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-31 00:33:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Call clean up functions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cancel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										setObjectLayer ( newObjectLayerFn ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										removeRoots ( [ ] string { fsDir } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-29 00:18:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ctx ,  cancel  :=  context . WithCancel ( context . Background ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  localMetacacheMgr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											localMetacacheMgr . deleteAll ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-14 18:08:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										initAllSubsystems ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										objLayer ,  fsDirs ,  err  :=  prepareErasureSets32 ( ctx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Initialization of object layer failed for Erasure setup: %s" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										setObjectLayer ( objLayer ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-18 05:42:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										initConfigSubsystem ( ctx ,  objLayer ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 02:39:57 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalIAMSys . Init ( ctx ,  objLayer ,  globalEtcdClient ,  2 * time . Second ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-09 23:14:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Executing the object layer tests for Erasure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objTest ( objLayer ,  ErasureTestStr ,  t ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-31 00:33:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-12 13:03:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										objLayer . Shutdown ( context . Background ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  localMetacacheMgr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											localMetacacheMgr . deleteAll ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										setObjectLayer ( newObjectLayerFn ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cancel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										removeRoots ( fsDirs ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-31 00:33:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-07 02:57:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ExecObjectLayerTestWithDirs - executes object layer tests.
  
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Creates single node and Erasure ObjectLayer instance and runs test for both the layers.
  
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ExecObjectLayerTestWithDirs ( t  TestErrHandler ,  objTest  objTestTypeWithDirs )  {  
						 
					
						
							
								
									
										
										
										
											2020-04-15 08:52:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx ,  cancel  :=  context . WithCancel ( context . Background ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  cancel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-20 16:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  localMetacacheMgr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										localMetacacheMgr . deleteAll ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									initAllSubsystems ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  fsDirs ,  err  :=  prepareErasure16 ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of object layer failed for Erasure setup: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-20 16:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									setObjectLayer ( objLayer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									initConfigSubsystem ( ctx ,  objLayer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									globalIAMSys . Init ( ctx ,  objLayer ,  globalEtcdClient ,  2 * time . Second ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Executing the object layer tests for Erasure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objTest ( objLayer ,  ErasureTestStr ,  fsDirs ,  t ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-20 16:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objLayer . Shutdown ( context . Background ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  localMetacacheMgr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										localMetacacheMgr . deleteAll ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									setObjectLayer ( newObjectLayerFn ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cancel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									removeRoots ( fsDirs ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 19:28:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-21 07:09:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ExecObjectLayerDiskAlteredTest - executes object layer tests while altering
  
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// disks in between tests. Creates Erasure ObjectLayer instance and runs test for Erasure layer.
  
						 
					
						
							
								
									
										
										
										
											2016-10-21 07:09:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ExecObjectLayerDiskAlteredTest ( t  * testing . T ,  objTest  objTestDiskNotFoundType )  {  
						 
					
						
							
								
									
										
										
										
											2020-04-15 08:52:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx ,  cancel  :=  context . WithCancel ( context . Background ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  cancel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  fsDirs ,  err  :=  prepareErasure16 ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of object layer failed for Erasure setup: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-08 09:15:04 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 00:18:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  objLayer . Shutdown ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 04:51:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-15 12:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  newTestConfig ( globalMinioDefaultRegion ,  objLayer ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Failed to create config directory" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Executing the object layer tests for Erasure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objTest ( objLayer ,  ErasureTestStr ,  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
  
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// files/directories under .minio/tmp.  Creates Erasure ObjectLayer instance and runs test for Erasure layer.
  
						 
					
						
							
								
									
										
										
										
											2016-06-29 17:28:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ExecObjectLayerStaleFilesTest ( t  * testing . T ,  objTest  objTestStaleFilesType )  {  
						 
					
						
							
								
									
										
										
										
											2020-04-15 08:52:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx ,  cancel  :=  context . WithCancel ( context . Background ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  cancel ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nDisks  :=  16 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									erasureDisks ,  err  :=  getRandomDisks ( nDisks ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-05 07:10:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of drives for Erasure setup: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-04 00:47:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objLayer ,  _ ,  err  :=  initObjectLayer ( ctx ,  mustGetPoolEndpoints ( 0 ,  erasureDisks ... ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-29 17:28:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Fatalf ( "Initialization of object layer failed for Erasure setup: %s" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-29 17:28:46 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-15 12:41:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  newTestConfig ( globalMinioDefaultRegion ,  objLayer ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatal ( "Failed to create config directory" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Executing the object layer tests for Erasure.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objTest ( objLayer ,  ErasureTestStr ,  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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-22 10:23:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  registerBucketLevelFunc ( bucket  * mux . Router ,  api  objectAPIHandlers ,  apiFunctions  ... string )  {  
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  apiFunction  :=  range  apiFunctions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  apiFunction  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "PostPolicy" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Register PostPolicy handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodPost ) . 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.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodGet ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . GetObjectHandler ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "PutObject" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register PutObject handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . PutObjectHandler ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "DeleteObject" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register Delete Object handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodDelete ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . DeleteObjectHandler ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "CopyObject" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register Copy Object  handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HeadersRegexp ( "X-Amz-Copy-Source" ,  ".*?(\\/|%2F).*?" ) . HandlerFunc ( api . CopyObjectHandler ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "PutBucketPolicy" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register PutBucket Policy handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodPut ) . HandlerFunc ( api . PutBucketPolicyHandler ) . Queries ( "policy" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "DeleteBucketPolicy" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register Delete bucket HTTP policy handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodDelete ) . HandlerFunc ( api . DeleteBucketPolicyHandler ) . Queries ( "policy" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "GetBucketPolicy" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register Get Bucket policy HTTP Handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodGet ) . HandlerFunc ( api . GetBucketPolicyHandler ) . Queries ( "policy" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:06:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "GetBucketLifecycle" : 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodGet ) . HandlerFunc ( api . GetBucketLifecycleHandler ) . Queries ( "lifecycle" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:06:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "PutBucketLifecycle" : 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodPut ) . HandlerFunc ( api . PutBucketLifecycleHandler ) . Queries ( "lifecycle" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-26 12:06:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "DeleteBucketLifecycle" : 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodDelete ) . HandlerFunc ( api . DeleteBucketLifecycleHandler ) . Queries ( "lifecycle" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "GetBucketLocation" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register GetBucketLocation handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodGet ) . HandlerFunc ( api . GetBucketLocationHandler ) . Queries ( "location" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "HeadBucket" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register HeadBucket handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodHead ) . HandlerFunc ( api . HeadBucketHandler ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-17 01:46:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "DeleteMultipleObjects" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Register DeleteMultipleObjects handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodPost ) . 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.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodPost ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . NewMultipartUploadHandler ) . Queries ( "uploads" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 01:38:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "CopyObjectPart" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Register CopyObjectPart handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 23:00:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HeadersRegexp ( "X-Amz-Copy-Source" ,  ".*?(\\/|%2F).*?" ) . HandlerFunc ( api . CopyObjectPartHandler ) . Queries ( "partNumber" ,  "{partNumber:.*}" ,  "uploadId" ,  "{uploadId:.*}" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "PutObjectPart" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register PutObjectPart handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 23:00:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodPut ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . PutObjectPartHandler ) . Queries ( "partNumber" ,  "{partNumber:.*}" ,  "uploadId" ,  "{uploadId:.*}" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "ListObjectParts" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register ListObjectParts handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodGet ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . ListObjectPartsHandler ) . Queries ( "uploadId" ,  "{uploadId:.*}" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "ListMultipartUploads" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register ListMultipartUploads handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodGet ) . HandlerFunc ( api . ListMultipartUploadsHandler ) . Queries ( "uploads" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "CompleteMultipart" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register Complete Multipart Upload handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodPost ) . Path ( "/{object:.+}" ) . HandlerFunc ( api . CompleteMultipartUploadHandler ) . Queries ( "uploadId" ,  "{uploadId:.*}" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-09 08:25:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "AbortMultipart" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Register AbortMultipart Handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodDelete ) . 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.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodGet ) . HandlerFunc ( api . GetBucketNotificationHandler ) . Queries ( "notification" ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  "PutBucketNotification" : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 08:02:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Register PutBucketNotification Handler.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodPut ) . HandlerFunc ( api . PutBucketNotificationHandler ) . Queries ( "notification" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  "ListenNotification" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Register ListenNotification Handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bucket . Methods ( http . MethodGet ) . HandlerFunc ( api . ListenNotificationHandler ) . Queries ( "events" ,  "{events:.*}" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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.
  
						 
					
						
							
								
									
										
										
										
											2018-04-22 10:23:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  registerAPIFunctions ( muxRouter  * mux . Router ,  objLayer  ObjectLayer ,  apiFunctions  ... string )  {  
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( apiFunctions )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Register all api endpoints by default.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-16 04:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										registerAPIRouter ( muxRouter ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// API Router.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									apiRouter  :=  muxRouter . PathPrefix ( SlashSeparator ) . Subrouter ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 23:23:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// 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`.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-29 05:14:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// When the handlers get a HTTP request they use the underlying 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-29 05:14:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// When cache is enabled, Put and Get operations are passed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// to underlying cache layer to manage object layer operation and disk caching
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// operation
 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									api  :=  objectAPIHandlers { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-31 14:39:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ObjectAPI :  func ( )  ObjectLayer  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-10 00:59:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  globalObjectAPI 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-31 14:39:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CacheAPI :  func ( )  CacheObjectLayer  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-10 00:59:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  globalCacheObjectAPI 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-31 14:39:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} , 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									apiRouter . Methods ( http . MethodGet ) . HandlerFunc ( api . ListBucketsHandler ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Register all bucket level handlers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									registerBucketLevelFunc ( bucketRouter ,  api ,  apiFunctions ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-13 11:04:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Takes in Erasure 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.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-08 13:43:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									muxRouter  :=  mux . NewRouter ( ) . SkipClean ( true ) . UseEncodedPath ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( apiFunctions )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Iterate the list of API functions requested for and register them in mux HTTP handler.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										registerAPIFunctions ( muxRouter ,  objLayer ,  apiFunctions ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-08 22:31:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										muxRouter . Use ( globalMiddlewares ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 03:48:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  muxRouter 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-16 04:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									registerAPIRouter ( muxRouter ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-08 22:31:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									muxRouter . Use ( globalMiddlewares ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-03 10:05:16 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  muxRouter 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-16 07:13:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-03 01:28:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  fmt . Errorf ( "failed to generate private key: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-03 01:28:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  fmt . Errorf ( "failed to generate serial number: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-03 01:28:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  nil ,  fmt . Errorf ( "Failed to create certificate: %w" ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 23:18:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-04-12 06:44:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-04 00:47:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  mustGetPoolEndpoints ( poolIdx  int ,  args  ... string )  EndpointServerPools  {  
						 
					
						
							
								
									
										
										
										
											2020-11-06 03:48:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									drivesPerSet  :=  len ( args ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									setCount  :=  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( args )  >=  16  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										drivesPerSet  =  16 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										setCount  =  len ( args )  /  16 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-20 22:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									endpoints  :=  mustGetNewEndpoints ( poolIdx ,  drivesPerSet ,  args ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-27 12:47:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  [ ] PoolEndpoints { { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-06 03:48:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										SetCount :      setCount , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DrivesPerSet :  drivesPerSet , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-20 09:42:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Endpoints :     endpoints , 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-15 02:32:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										CmdLine :       strings . Join ( args ,  " " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-20 09:42:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-20 22:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  mustGetNewEndpoints ( poolIdx  int ,  drivesPerSet  int ,  args  ... string )  ( endpoints  Endpoints )  {  
						 
					
						
							
								
									
										
										
										
											2019-11-20 09:42:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									endpoints ,  err  :=  NewEndpoints ( args ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-20 22:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-04 00:47:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i  :=  range  endpoints  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-20 22:48:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										endpoints [ i ] . SetPoolIndex ( poolIdx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										endpoints [ i ] . SetSetIndex ( i  /  drivesPerSet ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										endpoints [ i ] . SetDiskIndex ( i  %  drivesPerSet ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-04 00:47:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 06:44:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  endpoints 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-02 05:50:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getEndpointsLocalAddr ( endpointServerPools  EndpointServerPools )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  endpoints  :=  range  endpointServerPools  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-20 09:42:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  endpoint  :=  range  endpoints . Endpoints  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  endpoint . IsLocal  &&  endpoint . Type ( )  ==  URLEndpointType  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  endpoint . Host 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 06:44:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 15:37:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  net . JoinHostPort ( globalMinioHost ,  globalMinioPort ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-12 06:44:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-05-03 14:54:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// fetches a random number between range min-max.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  getRandomRange ( min ,  max  int ,  seed  int64 )  int  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// special value -1 means no explicit seeding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  seed  !=  - 1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rand . Seed ( seed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rand . Intn ( max - min )  +  min 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Randomizes the order of bytes in the byte array
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// using Knuth Fisher-Yates shuffle algorithm.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  randomizeBytes ( s  [ ] byte ,  seed  int64 )  [ ] byte  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// special value -1 means no explicit seeding.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  seed  !=  - 1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rand . Seed ( seed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									n  :=  len ( s ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  j  int 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  i  :=  0 ;  i  <  n - 1 ;  i ++  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										j  =  i  +  rand . Intn ( n - i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s [ i ] ,  s [ j ]  =  s [ j ] ,  s [ i ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-10-10 07:41:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  TestToErrIsNil ( t  * testing . T )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  toObjectErr ( nil )  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Errorf ( "Test expected to return nil, failed instead got a non-nil value %s" ,  toObjectErr ( nil ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  toStorageErr ( nil )  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Errorf ( "Test expected to return nil, failed instead got a non-nil value %s" ,  toStorageErr ( nil ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-13 03:07:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  context . Background ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  toAPIError ( ctx ,  nil )  !=  noError  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Errorf ( "Test expected error code to be ErrNone, failed instead provided %s" ,  toAPIError ( ctx ,  nil ) . Code ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-10 07:41:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Uploads an object using DummyDataGen directly via the http
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// handler. Each part in a multipart object is a new DummyDataGen
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// instance (so the part sizes are needed to reconstruct the whole
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// object). When `len(partSizes) == 1`, asMultipart is used to upload
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// the object as multipart with 1 part or as a regular single object.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// All upload failures are considered test errors - this function is
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// intended as a helper for other tests.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  uploadTestObject ( t  * testing . T ,  apiRouter  http . Handler ,  creds  auth . Credentials ,  bucketName ,  objectName  string ,  
						 
					
						
							
								
									
										
										
										
											2022-01-03 01:15:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									partSizes  [ ] int64 ,  metadata  map [ string ] string ,  asMultipart  bool , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  {  
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( partSizes )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										t . Fatalf ( "Cannot upload an object without part sizes" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( partSizes )  >  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										asMultipart  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									checkRespErr  :=  func ( rec  * httptest . ResponseRecorder ,  exp  int )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-08 02:18:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										t . Helper ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  rec . Code  !=  exp  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-20 02:05:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											b ,  err  :=  io . ReadAll ( rec . Body ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											t . Fatalf ( "Expected: %v, Got: %v, Body: %s, err: %v" ,  exp ,  rec . Code ,  string ( b ) ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! asMultipart  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										srcData  :=  NewDummyDataGen ( partSizes [ 0 ] ,  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										req ,  err  :=  newTestSignedRequestV4 ( http . MethodPut ,  getPutObjectURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											partSizes [ 0 ] ,  srcData ,  creds . AccessKey ,  creds . SecretKey ,  metadata ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Unexpected err: %#v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										checkRespErr ( rec ,  http . StatusOK ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Multipart upload - each part is a new DummyDataGen
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// (so the part lengths are required to verify the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// object when reading).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Initiate mp upload
 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reqI ,  err  :=  newTestSignedRequestV4 ( http . MethodPost ,  getNewMultipartURL ( "" ,  bucketName ,  objectName ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											0 ,  nil ,  creds . AccessKey ,  creds . SecretKey ,  metadata ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Unexpected err: %#v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  :=  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  reqI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										checkRespErr ( rec ,  http . StatusOK ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										decoder  :=  xml . NewDecoder ( rec . Body ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										multipartResponse  :=  & InitiateMultipartUploadResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  decoder . Decode ( multipartResponse ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Error decoding the recorded response Body" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										upID  :=  multipartResponse . UploadID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Upload each part
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  cp  [ ] CompletePart 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cumulativeSum  :=  int64 ( 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  i ,  partLen  :=  range  partSizes  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partID  :=  i  +  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											partSrc  :=  NewDummyDataGen ( partLen ,  cumulativeSum ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cumulativeSum  +=  partLen 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											req ,  errP  :=  newTestSignedRequestV4 ( http . MethodPut , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												getPutObjectPartURL ( "" ,  bucketName ,  objectName ,  upID ,  fmt . Sprintf ( "%d" ,  partID ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												partLen ,  partSrc ,  creds . AccessKey ,  creds . SecretKey ,  metadata ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  errP  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Unexpected err: %#v" ,  errP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rec  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											apiRouter . ServeHTTP ( rec ,  req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											checkRespErr ( rec ,  http . StatusOK ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 00:59:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											header  :=  rec . Header ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  v ,  ok  :=  header [ "ETag" ] ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												etag  :=  v [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  etag  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													t . Fatalf ( "Unexpected empty etag" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-30 07:57:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												cp  =  append ( cp ,  CompletePart { PartNumber :  partID ,  ETag :  etag [ 1  :  len ( etag ) - 1 ] } ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 00:59:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												t . Fatalf ( "Missing etag header" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Call CompleteMultipart API
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										compMpBody ,  err  :=  xml . Marshal ( CompleteMultipartUpload { Parts :  cp } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Unexpected err: %#v" ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-21 03:52:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reqC ,  errP  :=  newTestSignedRequestV4 ( http . MethodPost , 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											getCompleteMultipartUploadURL ( "" ,  bucketName ,  objectName ,  upID ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int64 ( len ( compMpBody ) ) ,  bytes . NewReader ( compMpBody ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											creds . AccessKey ,  creds . SecretKey ,  metadata ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  errP  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											t . Fatalf ( "Unexpected err: %#v" ,  errP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rec  =  httptest . NewRecorder ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										apiRouter . ServeHTTP ( rec ,  reqC ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										checkRespErr ( rec ,  http . StatusOK ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-05-24 21:26:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// unzip a file into a specific target dir - used to unzip sample data in cmd/testdata/
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  unzipArchive ( zipFilePath ,  targetDir  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									zipReader ,  err  :=  zip . OpenReader ( zipFilePath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  file  :=  range  zipReader . Reader . File  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										zippedFile ,  err  :=  file . Open ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  func ( )  ( err  error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defer  zippedFile . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											extractedFilePath  :=  filepath . Join ( targetDir ,  file . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  file . FileInfo ( ) . IsDir ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  os . MkdirAll ( extractedFilePath ,  file . Mode ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											outputFile ,  err  :=  os . OpenFile ( extractedFilePath ,  os . O_WRONLY | os . O_CREATE | os . O_TRUNC ,  file . Mode ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defer  outputFile . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_ ,  err  =  io . Copy ( outputFile ,  zippedFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}